sed:无法将 26 个项目写入标准输出:管道损坏



我有以下命令:

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

我错过了什么

正如@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,正如@triple所指出的,在管道开始时使用cat是无用的;您应该让awk直接读取文件,如下所示:

awk '{print $1, $6}' input.txt | ...

方法#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

这是一种蛮力,可能会导致你在未来错过另一个问题。

最新更新