考虑一个由单字组成的流,例如
$ echo foo bar baz quux xyxxy thud | tr ' ' '\n'
foo
bar
baz
quux
xyxxy
thud
我说“一个单词”是为了表示除了换行符之外没有空格。我想通过填写固定数量的字段(不是单个字符)每行,一次一行。对于少量数据,xargs 可以很好地完成此操作:
$ echo foo bar baz quux xyxxy thud | tr ' ' '\n' | xargs -n 2
foo bar
baz quux
xyxxy thud
但是这样使用 xargs 很慢。我有数百 GB 的文本需要处理,因此我非常希望我的写入吞吐量达到 50 MB/s 左右,我知道这个硬件可以做到(上面的 xargs 慢了几个数量级。)
标准工具箱中是否有更好的工具?如果需要,我可以写一些东西,但我更喜欢使用已有的文本过滤器。
答案1
我能想到的最好的办法是
$ echo foo bar baz quux xyxxy thud | tr'''\n'\ | perl -lne '$x.=" $_"; if(!($. % 2)){打印 $x; $x="";} END{打印 $x if $x}' 富吧 巴兹·库克斯 xyxxy 砰
或者可以说是更优雅的,尽管并不短
$ echo foo bar baz quux xyxxy thud bang| tr ' ' '\n' \ | perl -ne ‘chomp; 打印“$_ "; 打印“\n” if (!($. % 3)); END {打印“\n”}’ 巴兹酒吧 quux xyxxy 砰 砰
效率?
$ time perl -e ‘打印“foo\n”为(1..10000)’| xargs -n 3 > /dev/null 实际 0 分 1.330 秒 用户 0分0.500秒 系统 0 分 0.830 秒 $ time perl -e ‘打印“foo\n” for (1..10000)’ \ | perl -ne ‘chomp; 打印“$_ "; 打印“\n” if (!($. % 3)); END {打印“\n”}’ \ > /dev/null 实际 0分0.060秒 用户 0分0.030秒 系统 0分0.030秒
最初我尝试了 1000000 个单词,但是我厌倦了等待 xargs,尽管 perl 是 1.45 秒
(在 AMD-64 x2 5600+ 2.8GHz 处理器、4GB RAM 的 Vista-32 环境下对 andLinux 进行了计时)
答案2
pr
被严重低估了。以下是我得出的结论:
% echo foo bar baz quux xyxxy thud | tr ' ' '\n' | pr -2 -a -s' ' -t 富吧 巴兹·库克斯 xyxxy 砰 %
选项可能因系统而异;请参阅pr
手册页。
我没有尝试衡量它的性能。