Text-Processing

sed :以最後一次出現的模式結束範圍(貪婪範圍)

  • October 19, 2021

獲取以下文件:

$ 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第一個包含mnoGNU的所有行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

換句話說,有沒有辦法讓 GNUsed的範圍選擇變得貪婪?

更新

在我的設置中:

  • 如果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

請注意,當開始模式不存在時,這將不起作用,僅列印一系列空白行。

引用自:https://unix.stackexchange.com/questions/668793