Shell脚本中的算术运算失败

时间:2018-01-22 00:08:10

标签: bash shell unix

基本上我试图检查日志中是否有200个http响应,在最后3行。但我得到以下错误。因此,head命令失败。请帮助

    LINES=`cat http_access.log |wc -l`
    for i in  $LINES $LINES-1 $LINES-2

do
        echo "VALUE $i"
        head -$i http_access.log | tail -1 > holy.txt
        temp=`cat holy.txt| awk '{print $9}'`

        if [[ $temp == 200 ]]
        then
        echo "line $i has 200 code at "
        cat holy.txt | awk '{print $4}'
        fi
done

输出:

  

VALUE 18   第18行在[21 / Jan / 2018:15:34:23]有200个代码    VALUE 18-1   head:无效的尾随选项 - - 尝试`head --help'了解更多信息。

2 个答案:

答案 0 :(得分:3)

使用$((...))执行算术。

for i in $((LINES)) $((LINES-1)) $((LINES-2))

没有它,它正在尝试运行命令:

head -18 http_access.log
head -18-1 http_access.log
head -18-2 http_access.log

后两者是错误。

编写for循环的更灵活的方法是使用C风格的语法:

for ((i = LINES - 2; i <= LINES; ++i)); do
    ...
done

答案 1 :(得分:1)

您从JohnKugelman's answer获得 why ,我将提出一个可能适合您的简化代码:

while read -ra fields; do
    [[ ${fields[9]} = 200 ]] && echo "Line ${fields[0]} has 200 code: ${fields[4]}"
done < <(cat -n http_access.log | tail -n 3 | tac)
  • cat -n:文件的数字行
  • tail -n 3:打印最后3行。你可以改变这个数字以获得更多行
  • tac:以反向顺序打印tail输出的行
  • read -ra fields:将字段读入数组$fields
  • ${fields[0]}:行号
  • ${fields[num_of_field]}:个别字段

您也可以使用wc代替使用cat -n进行编号。对于较大的输入,这将稍微快一些:

lines=$(wc -l < http_access.log)
while read -ra fields; do
    [[ ${fields[8]} = 200 ]] && echo "Line $lines has 200 code: ${fields[3]}"
    ((lines--))
done < <(tail -n 3 http_access.log | tac)