[英]regex command line with single-line flag
我需要在bash
腳本中使用正則表達式來替換文件中可能位於多行的文本。
我會在我知道的其他正則表達式引擎中將s
作為標志傳遞,但我很難使用 bash。
據我所知, sed
不支持此功能。
perl
它顯然可以,但我不能讓它在一個襯里工作perl -i -pe 's/<match.+match>//s $file
示例文本:
DONT_MATCH
<match some text here
and here
match>
DONT_MATCH
默認情況下, .
不匹配換行符。 s
簡單地使.
匹配任何字符。
您一次讀取一行文件,因此您不可能匹配跨越多行的內容。 使用-0777
將整個輸入視為一行。
perl -i -0777pe's/<match.+match>//s' "$file"
這可能對您有用(GNU sed):
sed '/^<match/{:a;/match>$/!{N;ba};s/.*//}' file
從一個開始<match
to one end match>
收集一組行並將它們替換為空。
注意 這將對整個文件中的所有此類 collections 起作用,並且文件結束條件不會影響結果。 要僅對第一個采取行動,請使用:
sed '/^<match/{:a;/match>$/!{N;ba};s/.*//;:b;n;bb}' file
僅對第二個此類集合使用:
sed -E '/^<match/{:a;/match>$/!{N;ba};x;s/^/x/;/^(x{2})$/{x;s/.*//;x};x}' file
正則表達式/^(x{2})$/
可以定制以進行更復雜的匹配,例如/^(x|x{3,6})$/
將匹配第一個和第三個到第六個 collections。
使用 GNU sed:
$ sed -z 's/<match.*match>//g' file
DONT_MATCH
DONT_MATCH
對於任何 sed:
$ sed 'H;1h;$!d;x; s/<match.*match>//g' file
DONT_MATCH
DONT_MATCH
上述兩種方法都將整個文件讀入 memory。 如果您有一個大文件(例如千兆字節),您可能需要一種不同的方法。
在 GNU sed 中, -z
選項讀取以 NUL 作為記錄分隔符的文件。 對於從不包含 NUL 的文本文件,這具有讀取整個文件的效果。
對於普通的sed,可以通過以下步驟讀入整個文件:
H
- Append 電流線保持空間1h
- 如果這是第一行,用它覆蓋保持空間$!d
- 如果這不是最后一行,則刪除模式空間並跳轉到下一行。x
- 交換保持和模式空間以將整個文件放入模式空間
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.