Quindi, in generale, tendo a cercare l' sedelaborazione 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 kshe 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 sedcome:
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
kshusa ERE qui e sedun BRE. Ho fatto la stessa cosa con kshe un modello di shell prima, ma i risultati non differivano.
Comunque, questa è una discrepanza abbastanza significativa - kshsupera sed10 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 kshlascia davvero il suo offset proprio dove lo chiedi. Per ottenere (quasi) lo stesso da (GNU) sed devi usare -u- molto lentamente .
Ecco un grepv. kshTest:
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
kshi battiti grepqui - ma non sempre - sono praticamente legati. Tuttavia, è piuttosto eccellente e ksh fornisce un headinput 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;}"'
patternun'espressione regolare o un modello di shell più semplice?