我想刪除文件中特定行中匹配模式的特定連續兩行。
例如文件內容如下圖所示。
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
這由六個單獨的命令組成:
這兩個命令
s///
會套用於-,. j
以空格字元開頭的每一行。命令中的空正則表達式重複使用前一命令中的s
表達式(用於將一個或多個命令應用於與正規表示式匹配的行),因此該命令刪除以空格開頭的行上的第一個空格。然後該命令將修改後的行與前一行連接起來。這有效地取消了輸入資料中的換行。^
g
s
j
該命令
d
適用於所有以 開頭的行Name:
,並將其刪除。同樣,以 開頭的行將
SHA-256-Digest:
被刪除。從第 4 行開始刪除空白行。
我們將完整的緩衝區輸出到標準輸出以顯示結果。
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