Bu nedenle, genel olarak, sedmetin işlemeyi - özellikle büyük dosyalar için - arama eğilimindeyim ve genellikle kabuğun kendisinde bu tür şeyler yapmaktan kaçınırım.
Bence bu değişebilir. At etrafında alay man kshve bunu fark ettim:
<#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.
Gerçek dünyadaki kullanışlılığa şüpheyle bakmaya karar verdim. Yaptım:
seq -s'foo bar
' 1000000 >file
... bir milyon veri satırı için:
1foo bar
...
999999foo bar
1000000
... ve şuna sedbenzer:
p='^[^0-8]99999.*bar'
for c in "sed '/$p/q'" "ksh -c ':<##@(~(E)$p)'"
do </tmp/file eval "time ( $c )"
done | wc -l
Bu nedenle, her iki komut da 999999foo çubuğuna kadar olmalı ve kalıp eşleştirme uygulaması, bunu yapabilmek için her satırın en azından başlangıcını ve sonunu değerlendirmelidir. Ayrıca, ilk karakteri ihmal edilmiş bir desene karşı doğrulamaları gerekir. Bu basit bir şey, ama ... Sonuçlar beklediğim gibi değildi:
( 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
kshburada ERE ve sedbir BRE kullanır . Aynı şeyi daha kshönce bir kabuk deseni ile yaptım ama sonuçlar farklı değildi.
Her neyse, bu oldukça önemli bir tutarsızlık - 10 kat kshdaha iyi sed. Daha önce David Korn'un kendi io lib'ini yazdığını ve uyguladığını okumuştum ksh- muhtemelen bu ilgili mi? - ama onun hakkında hiçbir şey bilmiyorum. Kabuk bunu nasıl iyi yapıyor?
Benim için daha da şaşırtıcı olanı ksh, ofsetini gerçekten istediğiniz yerde bırakıyor. Almak için (neredeyse) aynı out (GNU) sed kullanmak zorunda -u- çok yavaş .
İşte bir grepv. kshTesti:
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
kshgrepburada atıyor - ama her zaman değil - hemen hemen bağlılar. Yine de, bu oldukça mükemmel ve ksh lookahead - head'in girişi maçtan önce başlıyor .
Sanırım gerçek olamayacak kadar iyi görünüyor. Bu komutlar kaputun altında ne yapıyor?
Oh, ve görünüşe göre burada bir alt kabuk bile yok:
ksh -c 'printf %.5s "${<file;}"'
patternbir düzenli ifade ya da daha basit kabuk desen?