有效地将输入的单字行条带化为列?


1

考虑一个单字行的流,例如stdout

$ 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慢了几个数量级。)

标准工具箱中有更好的东西吗?如果需要我可以写一些东西,但我更喜欢使用已经存在的文本过滤器。

Answers:


0

我能想到的最好的是

$ echo foo bar baz quux xyxxy thud | tr'''\ n'\
  | perl -lne'$ x。=“$ _”; if(!($。%2)){print $ x; $ x =“”;} END {print $ x if $ x}'
 foo吧
 巴兹楚克斯
 xyxxy thud

或者可以说更优雅,但不会更短

$ echo foo bar baz quux xyxxy thud bang | tr'''\ n'\
  | perl -ne'chomp; 打印“$ _”; 打印“\ n”if(!($。%3)); END {print“\ n”}'
foo bar baz
quux xyxxy thud
砰

效率?

$ time perl -e'print“foo \ n”for(1..10000)'| xargs -n 3> / dev / null

真正的0m1.330s
用户0m0.500s
sys 0m0.830s


$ time perl -e'print“foo \ n”for(1..10000)'\
  | perl -ne'chomp; 打印“$ _”; 打印“\ n”if(!($。%3)); END {print“\ n”}'\
  > / dev / null

真正的0m0.060s
用户0m0.030s
sys 0m0.030s

最初我尝试了1000000字,但厌倦了等待xargs虽然perl是1.45秒

(在AMD-64 x2 5600+ 2.8GHz,4GB RAM的Vista-32下,在andLinux上完成计时)


perl单行写入磁盘(在我的硬件上)写入磁盘大约20 MB / s,但是有足够的CPU可以管道它们。谢谢!
phs

0

pr被大大低估了。这是我想出的:

%echo foo bar baz quux xyxxy thud | tr'''\ n'| pr -2 -a -s'' -  t
foo吧
巴兹楚克斯
xyxxy thud
%

选项可能因系统而异; 看你的pr手册页。

我没有试图衡量这个的表现。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.