Quindi, in generale, tendo a cercare l' sed
elaborazione del testo - specialmente per file di grandi dimensioni - e di solito evito di fare quel genere di cose nella shell stessa.
Penso, tuttavia, che potrebbe cambiare. Stavo frugando in giro man ksh
e ho notato questo:
<#pattern Seeks forward to the beginning of the
next line containing pattern.
<##pattern The same as <# except that the por‐
tion of the file that is skipped is
copied to standard output.
Scettico sull'utilità del mondo reale, ho deciso di provarlo. L'ho fatto:
seq -s'foo bar
' 1000000 >file
... per un milione di righe di dati che sembrano:
1foo bar
...
999999foo bar
1000000
... e lo ha confrontato sed
come:
p='^[^0-8]99999.*bar'
for c in "sed '/$p/q'" "ksh -c ':<##@(~(E)$p)'"
do </tmp/file eval "time ( $c )"
done | wc -l
Quindi entrambi i comandi dovrebbero arrivare fino a 999999foo bar e la loro implementazione della corrispondenza del modello deve valutare almeno l'inizio e la fine di ogni riga per poterlo fare. Devono anche verificare il primo carattere rispetto a un modello negato. Questa è una cosa semplice, ma ... I risultati non erano quelli che mi aspettavo:
( sed '/^[^0-8]99999.*bar/q' ) \
0.40s user 0.01s system 99% cpu 0.419 total
( ksh -c ':<##@(~(E)^[^0-8]99999.*bar)' ) \
0.02s user 0.01s system 91% cpu 0.033 total
1999997
ksh
usa ERE qui e sed
un BRE. Ho fatto la stessa cosa con ksh
e un modello di shell prima, ma i risultati non differivano.
Comunque, questa è una discrepanza abbastanza significativa - ksh
supera sed
10 volte. Ho già letto che David Korn ha scritto il suo io lib e lo implementa ksh
- forse questo è legato? - ma non so quasi nulla al riguardo. Come mai la shell lo fa così bene?
Ancora più sorprendente per me è che ksh
lascia davvero il suo offset proprio dove lo chiedi. Per ottenere (quasi) lo stesso da (GNU) sed
devi usare -u
- molto lentamente .
Ecco un grep
v. ksh
Test:
1000000 #grep + head
( grep -qm1 '^[^0-8]99999.*bar'; head -n1; ) \
0.02s user 0.00s system 90% cpu 0.026 total
999999foo bar #ksh + head
( ksh -c ':<#@(~(E)^[^0-8]99999.*bar)'; head -n1; ) \
0.02s user 0.00s system 73% cpu 0.023 total
ksh
i battiti grep
qui - ma non sempre - sono praticamente legati. Tuttavia, è piuttosto eccellente e ksh
fornisce un head
input lookhead prima dell'inizio della partita.
Sembra troppo bello per essere vero, immagino. Cosa stanno facendo questi comandi in modo diverso sotto il cofano?
Oh, e apparentemente non c'è nemmeno una subshell qui:
ksh -c 'printf %.5s "${<file;}"'
pattern
un'espressione regolare o un modello di shell più semplice?