[英]Replace multiline string with sed
我有一個基本上是 INI/CFG 文件的文件,如下所示:
[thing-a]
attribute1=foo
attribute2=bar
attribute3=foobar
attribute4=barfoo
[thing-b]
attribute1=dog
attribute3=foofoo
attribute4=castles
[thing-c]
attribute1=foo
attribute4=barfoo
[thing-d]
attribute1=123455
attribute2=dogs
attribute3=biscuits
attribute4=1234
每個“事物”都有一組屬性,可以包括所有相同的屬性或其中的一個子集。
我正在嘗試編寫一個小的 bash 腳本,它將用預定義塊替換“thing-c”的屬性 $a1、$a2 和 $a3 在更廣泛的腳本的其他地方生成:
NEW_BLOCK="[thing-c]
attribute1=${a1}
attribute2=${a2}
attribute3=${a3}"
我可以像這樣找到帶有 sed 的正確塊:
THING_BLOCK=$(sed -nr "/^\[thing-c\]/ { :l /^\s*[^#].*/ p; n; /^\[/ q; b l; }" ./myThingFile)
我不確定我是不是掉進了兔子洞,或者這是怎么回事,我很確定有更好的方法可以做到這一點。
我想做的是:
sed "s/${THING_BLOCK}/${NEW_BLOCK}/"
但是我不太清楚這個的多線方面,我不確定最好的路線是什么。
有沒有辦法用 sed 進行這種多行查找和替換(或者使用 bash 的更好方法)
有沒有辦法進行這種多行查找和替換......
是的,確實有更好的方法,盡管使用awk
:
awk -v blk="$NEW_BLOCK" -v RS= '{ORS = RT} $1 == "[thing-c]" {$0 = blk} 1' file
使用-v RS=
我們使用一個空的記錄分隔符,在每個新行上拆分輸入文件中的記錄。
另一個 awk。將替換存儲到file2
並:
$ awk -v RS="" '
NR==FNR {
b=$0
next
}
$1~/thing-c/ {
$0=b
}
{
print (++c==1?"":ORS) $0
}' file2 file1
Output:
[thing-a]
attribute1=foo
attribute2=bar
attribute3=foobar
attribute4=barfoo
[thing-b]
attribute1=dog
attribute3=foofoo
attribute4=castles
[thing-c]
attribute1=${a1}
attribute2=${a2}
attribute3=${a3}
[thing-d]
attribute1=123455
attribute2=dogs
attribute3=biscuits
attribute4=1234
當您想使用sed
(恕我直言, awk
在這里更好)時,您必須擁有“不錯”的數據(沒有sed
將嘗試處理的特殊字符和[
inside block thing-3
)。
我測試過
read -d '' -r NEW_BLOCK <<END
[thing-c]
attribute1=${a1}
attribute2=${a2}
attribute3=${a3}
END
對於我的解決方案,我首先需要用兩個字符\n
替換$NEW_BLOCK
中的換行符。
echo "This is the replacement string: ${NEW_BLOCK//$'\n'/\\n}"
使用“多行”選項“-z”你可以
sed -rz "s/\[thing-c\][^[]*/${NEW_BLOCK//$'\n'/\\n}\n\n/" myThingFile
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.