如何用 sed 取代多行程式碼?

如何用 sed 取代多行程式碼?

我有一個大文件,其中包含特殊字元。那裡有一個多行程式碼,我想用sed.

這:

  text = "\
    ------                                                           ------\n\n\
    This message was automatically generated by email software\n\
    The delivery of your message has not been affected.\n\n\
    ------                                                           ------\n\n"

需要變成這樣:

text = ""

我嘗試了以下代碼,但沒有運氣:

sed -i '/  text = "*/ {N; s/  text = .*affected.\./  text = ""/g}' /etc/exim.conf

它不會替換任何內容,也不顯示任何錯誤訊息

我一直在玩它,但我嘗試的一切都不起作用。

答案1

Perl 來拯救:

perl -i~ -0777 -pe 's/text = "[^"]+"/text = ""/g' input-file
  • -i~將“就地”編輯文件,並留下備份副本
  • -0777一次讀取整個文件,而不是逐行讀取

替換的s///工作方式與 sed 類似(即,它匹配text = "後面跟有除雙引號之外的任何內容,多次直至雙引號),但在這種情況下,它適用於整個文件。

答案2

您必須檢查模式空間,N如果不匹配,請繼續拉入 ext 行,例如

sed '/text = "/{              # if line matches text = "
:b                            # label b
$!N                           # pull in the next line (if not the last one)
/"$/!bb                       # if pattern space doesn't end with " go to label b
s/".*"/""/                    # else remove everything between the quotes
}' infile

gnu sed可以把它寫成

sed '/text = "/{:b;$!N;/"$/!bb;s/".*"/""/}' infile

但這不是很有效,最好只選擇範圍/text = "/,/"/,修改第一行並刪除其餘的:

sed '/text = "/,/"/{            # in this range
/text = "/!d                    # delete all lines not matching text = "
s/\\/"/                         # replace the backslash with quotes (this is only
}' infile                       # executed if the previous d wasn't executed)

再次,gnu sed您可以將其寫為一行:

sed '/text = "/,/"/{/text = "/!d;s/\\/"/}' infile

答案3

就我個人而言,我會用 Perl 來做這件事。如果我們可以假設"在結束之前沒有",你可以這樣做:

perl -0pe 's/(text\s*=\s*)".*?"/$1""/s' file

吞食-0整個文件,將其讀入記憶體。意思-p是“在應用”給出的腳本後打印每一行(這裡,“行”將是整個文件)-e。該腳本本身是一個簡單的替換運算子。它將捕獲text後跟 0 個或多個空白字元的字串,然後=再捕獲 0 個或多個空白字元 ( text\s*=\s*) 並將其儲存為$1.然後,它將用模式 ( $1)和 替換捕獲的模式以及它找到的最短帶引號的字串""。該s標誌使.匹配換行符。

相關內容