簡體   English   中英

使用 sed 在最后一次出現模式后刪除特定行

[英]Using sed to delete specific lines after LAST occurrence of pattern

我有一個看起來像的文件:

this name
this age

Remove these lines and space above.
Remove here too and space below

Keep everything below here. 

我不想硬編碼 2,因為包含“this”的行數可以改變。 如何在最后一次出現字符串后刪除 4 行。 我正在嘗試sed -e '/this: /{n;N;N;N;N;d}'但它在第一次出現字符串后被刪除。

請您嘗試以下操作。

awk '
FNR==NR{
  if($0~/this/){
    line=FNR
  }
  next
}
FNR<=line || FNR>(line+4)
'  Input_file Input_file

Output 將如下所示樣品。

this: name
this: age
Keep everything below here.

您還可以使用此微小更改來使您的原始 sed 命令正常工作。

sed '/^this:/ { :k ; n ; // b k ; N ; N ; N ; d }' input_file

它使用一個循環打印當前行並讀取下一行( n ),同時它保持匹配正則表達式(空正則表達式//調用最新評估的行,即/^this:/ ,並且命令bk回到label k上一場比賽)。 然后你可以 append 接下來的 3 行並像你一樣刪除整個模式空間。

使用 GNU sed 的另一種更簡潔的可能性可能是這樣。

sed '/^this:/ b ; /^/,$ { //,+3 d }' input_file

這個打印任何this:沒有 label 的b在默認打印操作后直接進入下一行循環)。

this:不匹配的第一行中,觸發了兩個嵌套范圍。 外部范圍是“一次性”。 由於/^/與任何行匹配,它會立即觸發,然后它會一直觸發到最后一行( $ )。 內部范圍是“切換”范圍。 它也被立即觸發,因為//在這一行召回/^/ (並且僅在這一行,因此單次外部范圍)然后它保持觸發 3 個額外的行(結束地址+3是 GNU 擴展) . 之后, /^/不再被評估,因此內部范圍不能再次觸發,因為//召回/^this:/ (這是早期的捷徑)。

這可能對您有用(GNU sed):

sed -E ':a;/this/n;//ba;$!N;$!ba;s/^([^\n]*\n?){4}//;/./!d' file 

如果模式空間 (PS) 包含this ,則打印 PS 並獲取下一行。

如果以下行包含this重復。

如果當前行不是最后一行,則 append 下一行並重復。

否則,刪除 PS 的前四行並打印剩余部分。

除非 PS 為空,在這種情況下完全刪除 PS。

注意這只會讀取一次文件。 OP還說

如何在最后一次出現字符串后刪除 4 行

但是,該示例似乎期望刪除 5 行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM