Bu nedenle, genel olarak, sed
metin 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 ksh
ve 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 sed
benzer:
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
ksh
burada ERE ve sed
bir 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 ksh
daha 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 grep
v. ksh
Testi:
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
grep
burada 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;}"'
pattern
bir düzenli ifade ya da daha basit kabuk desen?