Striscia efficacemente le righe di una parola in arrivo su colonne?


1

Considera un flusso di righe di una parola come stdout di

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

Dico "una sola parola" per indicare che non vi è spazio bianco diverso dalle nuove righe. Vorrei "dividere in colonne" i dati compilando un numero fisso di campi (non singoli caratteri) per riga, una riga alla volta. Per piccole quantità di dati, xargs lo fa bene:

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

Comunque usare xargs in questo modo è lento. Ho centinaia di gigabyte di testo da elaborare, quindi mi piacerebbe molto che il mio throughput di scrittura raggiungesse i 50 MB / s o così so che questo hardware può fare (gli xarg sopra sono ordini di grandezza più lenti.)

C'è qualcosa di meglio disponibile nella cassetta degli attrezzi standard? Posso scrivere qualcosa, se necessario, ma preferirei usare un filtro di testo che è già lì.

Risposte:


0

Il meglio che posso inventare è

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

o forse più elegante, anche se non più breve

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

Efficienza?

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

0m1.330 reali
utente 0m0.500s
sys 0m0.830s


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

0m0.060 reali
utente 0m0.030s
sys 0m0.030s

Inizialmente ho provato 1000000 parole ma mi sono stufato aspettando xargs sebbene il perl fosse 1,45s

(Tempi eseguiti su andLinux sotto Vista-32 su un AMD-64 x2 5600+ 2.8GHz con 4 GB di RAM)


Il perl one-liner colpisce circa 20 MB / s in scrittura sul disco (sul mio hardware), ma è rimasta abbastanza CPU che posso pipeline. Grazie!
phs,

0

prè ampiamente sottovalutato. Ecco cosa mi è venuto in mente:

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

Le opzioni possono variare tra i sistemi; vedi la tua prpagina man.

Non ho tentato di misurare le prestazioni di questo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.