【问题标题】:Evaluating a log file using a sh script使用 sh 脚本评估日志文件
【发布时间】:2019-04-24 15:19:38
【问题描述】:

我有一个包含很多行的日志文件,格式如下:

IP - - [Timestamp Zone] 'Command Weblink Format' - size

我想写一个 script.sh 来告诉我每个网站被点击的次数。 命令

awk '{print $7}' server.log | sort -u

应该给我一个列表,将每个唯一的网络链接放在一个单独的行中。命令

grep 'Weblink1' server.log | wc -l

应该给我点击 Weblink1 的次数。我想要一个命令,将上面的 Awk 命令创建的每一行转换为一个变量,然后创建一个循环,在提取的 web 链接上运行 grep 命令。我可以使用

while IFS='' read -r line || [[ -n "$line" ]]; do
    echo "Text read from file: $line"
done

(来源:Read a file line by line assigning the value to a variable)但我不想将 Awk 脚本的输出保存在 .txt 文件中。

我的猜测是:

while IFS='' read -r line || [[ -n "$line" ]]; do
    grep '$line' server.log | wc -l | ='$variabel' |
    echo " $line was clicked $variable times "
done

但我不太熟悉循环连接命令,因为这是我第一次。这个循环可以工作吗?如何连接我的循环和 Awk 脚本?

【问题讨论】:

    标签: bash loops sh


    【解决方案1】:

    循环中的 Shell 命令的连接方式与没有循环时的连接方式相同,而且您不是很接近。但是,是的,如果您出于某种原因(例如学习体验)想要这种极其低效的方式,则可以循环完成:

    awk '{print $7}' server.log |
    sort -u |
    while IFS= read -r line; do 
      n=$(grep -c "$line" server.log)
      echo "$line" clicked $n times
    done 
    
    # you only need the read || [ -n ] idiom if the input can end with an
    # unterminated partial line (is illformed); awk print output can't.
    # you don't really need the IFS= and -r because the data here is URLs 
    # which cannot contain whitespace and shouldn't contain backslash,
    # but I left them in as good-habit-forming.
    
    # in general variable expansions should be doublequoted
    # to prevent wordsplitting and/or globbing, although in this case 
    # $line is a URL which cannot contain whitespace and practically 
    # cannot be a glob. $n is a number and definitely safe.
    
    # grep -c does the count so you don't need wc -l
    

    或者更简单的

    awk '{print $7}' server.log |
    sort -u |
    while IFS= read -r line; do 
      echo "$line" clicked $(grep -c "$line" server.log) times
    done 
    

    但是,如果您只想要正确的结果,那么在 awk 中一次性完成会更高效且更简单:

    awk '{n[$7]++}
        END{for(i in n){
            print i,"clicked",n[i],"times"}}' |
    sort
    
    # or GNU awk 4+ can do the sort itself, see the doc:
    awk '{n[$7]++}
        END{PROCINFO["sorted_in"]="@ind_str_asc";
        for(i in n){
            print i,"clicked",n[i],"times"}}'
    

    关联数组n 收集来自第七个字段的值作为键,并且在每一行上,提取的键的值递增。因此,最后n中的keys是文件中的所有URL,每个值是它出现的次数。

    【讨论】:

    • 也许要强调在整个文件上运行 grep 的次数与日志文件中的唯一 URL 一样多会非常慢。
    猜你喜欢
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 2014-07-04
    • 1970-01-01
    • 1970-01-01
    • 2017-01-03
    • 2015-08-04
    相关资源
    最近更新 更多