Shell腳本:想要從特定行中刪除匹配模式的兩個連續行

Shell腳本:想要從特定行中刪除匹配模式的兩個連續行

我想刪除文件中特定行中匹配模式的特定連續兩行。

例如文件內容如下圖所示。

Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5:  xyz
Line6: Name: 456
Line7:  abc

我想找到從第 4 行開始的行,匹配以“Name:”開頭的第一行模式,匹配以空格開頭的第二行模式,並刪除連續的兩行。

有什麼有效的方法可以使用 shellsed或其他方法來執行此操作嗎?

更清楚地說,我想從 MANIFEST.MF 中刪除簽名/校驗和資訊。

範例 MANIFEST.MF 如下所示: 從下面的清單檔案中,我想刪除條目「Name:」。其中「名稱:」條目可以位於一行或兩行(或更多)行。

最初我的解決方案就像找到第一個“Name:”條目,然後是“SHA-256-Digest:”條目並刪除到檔案末尾。不幸的是,該解決方案存在刪除中間所需條目的問題。例如,「NetBeans-Simply-Convertible:」也會被刪除。

因此,現在我想刪除“Name:”條目(如果在 1 行中可用)或跨越 2 行或更多行的條目。但在刪除「Name:」條目時,我不應該遺失「NetBeans-Simply-Convertible:」等條目。

我已經使用以下命令刪除檔案中的“SHA-256-Digest:”條目sed -i "/^\SHA-256-Digest: /d" $manifest_file


Manifest-Version: 1.0
Version-Info: ....

Name: com/abc/xyz/pqr/client/relationship/message/notifier/Relati
 onshipUpdateNotifierFactory.class
SHA-256-Digest: cSSyk6Y2L2F9N6FPtswUkxjF2kelMkGe4bFprcQ+3uY=

Name: com/abc/xyz/pqr/client/relationship/ui/BaseRelationshipView
 $5.class
SHA-256-Digest: w9HgRjDuP024U4CyxeKPYFe6rzuzxZF3b+9LVG36XP8=

Name: com/abc/xyz/pqr/client/impl/MofRelationshipAgentImpl.class
SHA-256-Digest: GwIBIU+UdPtjyRhayAVM90Eo+SwCT/kP65dI59adEnM=

Name: com/abc/xyz/pqr/client/settings/ConvertibleProperties.class
NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
 vertibleProperties
SHA-256-Digest: 5FszAtfpPXcLx/6FBWbfeg6E4fwFMRozV+Q+3rReATc= ...

預期輸出:

Manifest-Version: 1.0
Version-Info: ....


NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
 vertibleProperties

...

答案1

awk方法:

假設我們有以下輸入檔案file.txt(考慮到每行包含Line<number>:第一個欄位):

Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5:  xyz
Line6: Name: 456
Line7:  abc
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11:  abc
Line12: Name: 333
Line13:  ccc

awk '{ if ($2 == "Name:") { 
           if ((getline l) > 0){ 
               if (l ~ /^\S+  \S+/) { next } else { print $0 RS l }               
           }
       } else { print } 
}' file.txt

輸出:

Line1: a
Line2: b
Line3: c
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11:  abc

'取得線變數'- 從 awk 的輸入讀取下一筆記錄到變數中var

取得線如果命令找到一筆記錄,則傳回 1;如果遇到文件末尾,則傳回 0。

答案2

你看你問的不清楚:一個答案刪除了 4 行(配對的兩行和後續的兩行);另一個刪除所有內容匹配的線...

我將添加我所理解的你想要的內容:我刪除 2 行,匹配的一行Name: 123和後續的一行。我用以下方法做到這一點sed

sed -e '/Name: 123/{N;d}' filename

答案3

使用ed

$ printf '%s\n' 'g/^ / s///\' '-,.j' 'g/^Name: /d' 'g/SHA-256-Digest: /d' '4,$g/^$/d' ,p Q | ed -s file
Manifest-Version: 1.0
Version-Info: ....

NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}ConvertibleProperties

這會將以下編輯腳本套用至您的輸入檔:

g/^ / s///\
-,.j
g/^Name: /d
g/SHA-256-Digest: /d
4,$g/^$/d
,p
Q

這由六個單獨的命令組成:

  1. 這兩個命令s///會套用於-,. j以空格字元開頭的每一行。命令中的空正則表達式重複使用前一命令中的s表達式(用於將一個或多個命令應用於與正規表示式匹配的行),因此該命令刪除以空格開頭的行上的第一個空格。然後該命令將修改後的行與前一行連接起來。這有效地取消了輸入資料中的換行。^gsj

  2. 該命令d適用於所有以 開頭的行Name:,並將其刪除。

  3. 同樣,以 開頭的行將SHA-256-Digest:被刪除。

  4. 從第 4 行開始刪除空白行。

  5. 我們將完整的緩衝區輸出到標準輸出以顯示結果。

  6. Q無條件退出編輯器(您可以wq將變更寫回原始檔案)。

答案4

sed -e '
   4,$!d;      # skip non-relevant portion
   /Name:/N;   # grab the line coming after Name:
   /\n.* /d;   # what we were after is not this
   P;D
' yourfile

相關內容