Inilah cara lain dengan sed
:
sed '/foo/,$!d;H;/bar/!d;s/.*//;x;s/\n//' infile
Ini menambahkan setiap baris dalam /foo/,$
jangkauan (garis !
- garis yang tidak dalam kisaran ini d
dihapus) ke H
ruang lama. Baris yang tidak cocok bar
kemudian dihapus. Pada garis yang cocok, ruang pola dikosongkan, e x
diubah dengan ruang tahan dan garis kosong terkemuka di ruang pola dihapus.
Dengan input besar dan beberapa kemunculan bar
hal ini seharusnya (jauh) lebih cepat daripada menarik setiap garis ke dalam ruang pola dan kemudian, setiap kali, memeriksa ruang pola bar
.
Dijelaskan:
sed '/foo/,$!d # delete line if not in this range
H # append to hold space
/bar/!d # if it doesn't match bar, delete
s/.*// # otherwise empty pattern space and
x # exchange hold buffer w. pattern space then
s/\n// # remove the leading newline
' infile
Tentu, jika ini adalah file (dan sesuai dengan memori) Anda bisa menjalankan:
ed -s infile<<'IN'
.t.
/foo/,?bar?p
q
IN
karena ed
bisa mencari maju dan mundur.
Anda bahkan bisa membaca output perintah ke buffer teks jika shell Anda mendukung substitusi proses:
printf '%s\n' .t. /foo/,?bar?p q | ed -s <(your command)
atau jika tidak, dengan gnu ed
:
printf '%s\n' .t. /foo/,?bar?p q | ed -s '!your command'
foo
dan terakhirbar
dan mencetak semuanya di antaranya, jika ada. Dengan stream Anda harus membaca sampai yang pertamafoo
, dan buffer semua baris berikutnya dalam memori sampai EOF, flushing buffer setiap kali abar
terlihat. Ini bisa berarti buffering seluruh aliran dalam memori.