
我有一個大文件,其中包含特殊字元。那裡有一個多行程式碼,我想用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
標誌使.
匹配換行符。