我有以下命令:
cat input.txt | awk '{print $1, $6}' | sort -n | uniq -c | sort -nr | sed 's/"//g'| head -10
我得到了所需的输出,但是出现了这个错误
sed: couldn't write 26 items to stdout: Broken pipe
其中input.txt类似于:
192.168.2.20 - - [28/Jul/2006:10:27:10 -0300] "GET /cgi-bin/try/ HTTP/1.0" 200 3395
127.0.0.1 - - [28/Jul/2006:10:22:04 -0300] "GET / HTTP/1.0" 200 2216
我想念什么
答案 0 :(得分:1)
正如@KamilCuk在评论中所说,之所以发生是因为head -10
仅从管道读取前10行(可能还有一些输入缓冲),然后将其关闭;如果输入足够大,则会在sed
将所有内容写入管道之前发生(管道的缓冲区不足以吸收多余的空间)。因此,是否发生这种情况取决于输入大小,操作系统及其参数(确定管道的特性),sed
在其输出下降时的行为等。只需稍微改变一下内容就足以避免出现问题,例如:
...sort -nr | tr -d '"' | head -10 # use `tr` instead of `sed` -- it may behave differently
...sort -nr | head -10 | sed 's/"//g' # swap `head` and `sed` -- now `sort`'s output is dropped
以下是将避免出现的错误:
...sort -nr | sed '11,$ d; s/"//g'
此方法的工作原理是告诉sed
丢弃第11行到输入(“ $”)的末尾,但是由于它会在 读取后丢弃它们(而不是从不读取)首先,例如head -10
),sort
的整个输出将被读取,并且不会发生错误。
BTW在管道的开头使用cat
是没有用的;您应该awk
直接读取文件,如下所示:
awk '{print $1, $6}' input.txt | ...
答案 1 :(得分:1)
方法1:将sed移至末尾
cat input.txt | awk '{print $1, $6}' | sort -n | uniq -c | sort -nr | head -10 | sed 's/"//g'
这在语义上是相同的。通过在末尾加上sed,可以得到所需的格式,但可以避免出现错误消息。
方法2:忽略错误消息。
cat input.txt | awk '{print $1, $6}' | sort -n | uniq -c | sort -nr | sed 's/"//g' 2>/dev/null | head -10
这是蛮力的,将来可能会导致您错过另一个问题。