簡體   English   中英

帶有單行標志的正則表達式命令行

[英]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.

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