Jadi, secara umum, saya cenderung mencari sedpengolahan teks - terutama untuk file besar - dan biasanya menghindari melakukan hal-hal di shell itu sendiri.
Saya pikir, itu mungkin berubah. Saya mencari-cari man kshdan memperhatikan ini:
<#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.
Skeptis tentang kegunaan dunia nyata, saya memutuskan untuk mencobanya. Aku melakukannya:
seq -s'foo bar
' 1000000 >file
... untuk sejuta baris data yang terlihat seperti:
1foo bar
...
999999foo bar
1000000
... dan mengadu itu sedseperti:
p='^[^0-8]99999.*bar'
for c in "sed '/$p/q'" "ksh -c ':<##@(~(E)$p)'"
do </tmp/file eval "time ( $c )"
done | wc -l
Jadi kedua perintah harus mendapatkan bar 999999foo dan implementasi pencocokan pola mereka harus mengevaluasi setidaknya awal dan akhir setiap baris untuk melakukannya. Mereka juga harus memverifikasi char pertama terhadap pola yang dinegasikan. Ini adalah hal yang sederhana, tapi ... Hasilnya tidak seperti yang saya harapkan:
( 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
kshmenggunakan ERE di sini dan sedBRE. Saya melakukan hal yang sama dengan kshdan pola shell sebelumnya tetapi hasilnya tidak berbeda.
Bagaimanapun, itu perbedaan yang cukup signifikan - kshmengungguli sed10 kali lipat. Saya telah membaca sebelumnya bahwa David Korn menulis io lib-nya sendiri dan mengimplementasikannya ksh- mungkin ini terkait? - tapi saya tidak tahu apa-apa tentang itu. Bagaimana cangkangnya melakukan ini dengan sangat baik?
Bahkan yang lebih menakjubkan bagi saya adalah kshbenar - benar meninggalkan offset tepat di tempat Anda memintanya. Untuk mendapatkan (hampir) sama dengan (GNU) sed Anda harus menggunakan -u- sangat lambat .
Inilah tes grepv ksh.:
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
kshberdetak di grepsini - tetapi tidak selalu - mereka cukup terikat. Namun, itu cukup bagus, dan ksh memberikan headmasukan lookahead - dimulai sebelum pertandingan.
Sepertinya terlalu bagus untuk menjadi kenyataan, kurasa. Apa yang dilakukan perintah-perintah ini secara berbeda di bawah tenda?
Oh, dan ternyata tidak ada subkulit di sini:
ksh -c 'printf %.5s "${<file;}"'
patternekspresi reguler atau pola shell yang lebih sederhana?