使用sed进行管道传输时出现问题

5

我在使用sed命令时遇到了问题。一旦我将输出通过管道传递给sed,我就无法将sed的输出再次通过管道传递到其他地方。

wget -r -nv http://127.0.0.1:3000/test.html

输出:

2010-03-12 04:41:48 URL:http://127.0.0.1:3000/test.html [99/99] -> "127.0.0.1:3000/test.html" [1]
2010-03-12 04:41:48 URL:http://127.0.0.1:3000/robots.txt [83/83] -> "127.0.0.1:3000/robots.txt" [1]
2010-03-12 04:41:48 URL:http://127.0.0.1:3000/shop [22818/22818] -> "127.0.0.1:3000/shop.29" [1]

我将输出通过sed传输,以获得干净的URL列表:
wget -r -nv http://127.0.0.1:3000/test.html 2>&1 | grep --line-buffered -v ERROR | sed 's/^.*URL:\([^ ]*\).*/\1/g'

输出:

http://127.0.0.1:3000/test.html
http://127.0.0.1:3000/robots.txt
http://127.0.0.1:3000/shop

我想把输出内容保存到文件中,所以我这样做:

wget -r -nv http://127.0.0.1:3000/test.html 2>&1 | grep --line-buffered -v ERROR | sed 's/^.*URL:\([^ ]*\).*/\1/g' > /tmp/DUMP_FILE

几秒钟后,我中断了进程并检查文件,但是文件是空的。

有趣的是,以下命令没有输出(与上面相同,但将sed输出通过cat管道传输):

wget -r -nv http://127.0.0.1:3000/test.html 2>&1 | grep --line-buffered -v ERROR | sed 's/^.*URL:\([^ ]*\).*/\1/g' | cat

为什么我不能将sed的输出导入到像cat这样的其他程序中?

sed应该可以与管道一起正常工作,例如:echo "foo" | sed 's/foo/bar/g' >/tmp/foo 对我来说很好用。在sed中添加-u选项会有什么区别吗?或者尝试让进程完成后再检查文件。sed可能只是对结果进行了太多的内部缓冲。 - bdk
2个回答

9

当sed写入另一个进程或文件时,它会缓冲数据。

尝试在sed命令中添加--unbuffered选项。


1

你也可以使用awk。由于你的URL出现在第3个字段中,所以你可以使用$3,并且你也可以去掉grep。

awk '!/ERROR/{sub("URL:","",$3);print $3}' file

为什么不从今天开始呢? :) - ghostdog74

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接