Đâ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 dxóa bỏ) vào Hkhông gian cũ. Các dòng không khớp barsẽ bị xóa. Trên các dòng khớp, không gian mẫu được làm trống, e xthay đổ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'
foovà cuối cùngbarvà 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ênfoovà đệm tất cả các dòng tiếp theo trong bộ nhớ cho đến EOF, xả bộ đệm mỗi khibarnhìn thấy a. Điều này có thể có nghĩa là đệm toàn bộ luồng trong bộ nhớ.