簡體   English   中英

用 sed 替換多行字符串

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

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