Text-Processing
sed :以最後一次出現的模式結束範圍(貪婪範圍)
獲取以下文件:
$ cat f1 stu vwx yza uvw xyz abc abc def ghi def ghi jkl ghi jkl mno jkl mno pqr mno pqr stu pqr stu vwx stu vwx yza
要列印從第一個包含
abc
到第一個包含mno
GNU的所有行sed
:$ sed -n '/abc/,/mno/p' f1 uvw xyz abc abc def ghi def ghi jkl ghi jkl mno
我怎樣才能列印所有行,直到最後一個包含
mno
,例如我怎樣才能得到以下結果:uvw xyz abc abc def ghi def ghi jkl ghi jkl mno jkl mno pqr mno pqr stu
換句話說,有沒有辦法讓 GNU
sed
的範圍選擇變得貪婪?更新
在我的設置中:
- 如果
mno
失去,它應該列印出所有內容,直到文件結束。mno
不能發生在第一個之前abc
。- 總是至少有一個
abc
,並且abc
永遠mno
不會在同一條線上編輯 我只是在開頭添加了一個虛擬
stu vwx yza
行,這樣文件就不會以包含的行開頭abc
(以避免從第一行開始的解決方案 - 它們應該從其中包含的第一行開始abc
)
sed '/abc/,$!d;0,/mno/b;:1;/mno/b;$d;N;b1' file
工作算法:
使用兩個地址範圍。
第一個
/abc/,$!d;
刪除直到第一個模式匹配的所有內容。與模式匹配的第二個,將每一行緩衝區(模式空間)發送到輸出繞過剩餘的腳本,從而防止在文件中找不到模式時刪除。 腳本的其餘部分循環工作。在編輯器緩衝區中,添加行直到發生模式匹配。如果遇到模式,則將整個緩衝區發送到輸出,繞過腳本的其餘部分。如果不匹配,則在最後一行刪除緩衝區。
0,/mno/b;``/mno/
:1;/mno/b;$d;N;b1``/mno/
awk
如果它是一個選項,你可以使用。您可以標記模式開始和模式停止的行,並在文件的一次傳遞中列印這些行(涉及儲存從第一行開始的行,abc
直到緩衝區中的最後一行)awk '/abc/ && !start { start = NR } /mno/ { stop = NR } start { line[NR] = $0 } END { if ( !stop ) { stop = NR } for ( s = start; s <= stop; s++ ) print line[s] }' file
請注意,當開始模式不存在時,這將不起作用,僅列印一系列空白行。