Listra eficientemente linhas de uma palavra entrando em colunas?

1

Considere um fluxo de linhas de uma só palavra, como o stdout de

$ echo foo bar baz quux xyxxy thud | tr ' ' '\n'
foo
bar
baz
quux
xyxxy
thud

Eu digo "uma palavra" para indicar que não há espaços em branco que não sejam as novas linhas. Eu gostaria de "colocar em coluna" os dados preenchendo um número fixo de campos (não caracteres únicos) por linha, uma linha por vez. Para pequenas quantidades de dados, o xargs faz isso muito bem:

$ echo foo bar baz quux xyxxy thud | tr ' ' '\n' | xargs -n 2
foo bar
baz quux
xyxxy thud

No entanto, o uso de xargs dessa maneira é lento. Eu tenho centenas de gigabytes de texto para processar, então eu gostaria muito do meu throughput de gravação para atingir os 50 MB / s ou algo que eu sei que esse hardware pode fazer (os xargs acima são ordens de magnitude mais lentas).

Existe algo melhor disponível na caixa de ferramentas padrão? Eu posso escrever algo, se necessário, mas eu prefiro usar um filtro de texto que já está lá.

    
por phs 03.09.2011 / 09:05

2 respostas

0

O melhor que posso encontrar é

$ echo foo bar baz quux xyxxy thud | tr ' ' '\n' \
  | perl -lne '$x.=" $_"; if(!($. % 2)){print $x; $x="";} END{print $x if $x}'
 foo bar
 baz quux
 xyxxy thud

ou o indiscutivelmente mais elegante, embora não mais curto

$ echo foo bar baz quux xyxxy thud bang| tr ' ' '\n' \
  | perl -ne 'chomp; print "$_ "; print "\n" if (!($. % 3)); END {print "\n"}'
foo bar baz
quux xyxxy thud
bang

Eficiência?

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

real    0m1.330s
user    0m0.500s
sys     0m0.830s


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

real    0m0.060s
user    0m0.030s
sys     0m0.030s

Inicialmente, eu tentei o 1000000, mas me cansei de esperar pelos xargs, embora o perl tenha sido 1.45s

(Temporizações feitas no andLinux no Vista-32 em um AMD-64 x2 5600+ 2.8GHz com 4GB de RAM)

    
por 03.09.2011 / 20:49
0

pr é muito subestimado. Eis o que eu criei:

% echo foo bar baz quux xyxxy thud | tr ' ' '\n' | pr -2 -a -s' ' -t
foo bar
baz quux
xyxxy thud
%

As opções podem variar entre sistemas; veja sua página pr man.

Eu não fiz nenhuma tentativa de medir o desempenho disso.

    
por 20.04.2013 / 04:36