Đây là một cách khác với sed
:
sed '/foo/,$!d;H;/bar/!d;s/.*//;x;s/\n//' infile
Nó nối từng dòng trong /foo/,$
phạm vi (các dòng !
không nằm trong phạm vi này được d
xóa bỏ) vào H
không gian cũ. Các dòng không khớp bar
sẽ bị xóa. Trên các dòng khớp, không gian mẫu được làm trống, e x
thay đổi với không gian giữ và dòng trống hàng đầu trong không gian mẫu được loại bỏ.
Với đầu vào lớn và một vài lần xuất hiện, bar
điều này sẽ nhanh hơn (nhiều) so với việc kéo từng dòng vào không gian mẫu và sau đó, mỗi lần, kiểm tra không gian mẫu cho bar
.
Giải thích:
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
Chắc chắn, nếu đây là một tệp (và vừa với bộ nhớ), bạn có thể chỉ cần chạy:
ed -s infile<<'IN'
.t.
/foo/,?bar?p
q
IN
bởi vì ed
có thể tìm kiếm tiến và lùi.
Bạn thậm chí có thể đọc một đầu ra lệnh vào bộ đệm văn bản nếu trình bao của bạn hỗ trợ thay thế quá trình:
printf '%s\n' .t. /foo/,?bar?p q | ed -s <(your command)
hoặc nếu không, với gnu ed
:
printf '%s\n' .t. /foo/,?bar?p q | ed -s '!your command'
foo
và cuối cùngbar
và in mọi thứ ở giữa, nếu có. Với một luồng bạn sẽ phải đọc cho đến đầu tiênfoo
và đệm tất cả các dòng tiếp theo trong bộ nhớ cho đến EOF, xả bộ đệm mỗi khibar
nhìn thấy a. Điều này có thể có nghĩa là đệm toàn bộ luồng trong bộ nhớ.