
我有一個文件,其中包含一些文字和 - 在一行上 - 一個指示應在何處添加新內容的標記
foo
bar
%SUBSTITUTE%
foo
行行替代應替換為新的多行字串text="some text"
(請注意,我不知道該字串,例如它可能是讀取文件 cat“file”`` 的結果text=
)。替換的結果應為
foo
bar
some text
%SUBSTITUTE%
foo
我有一個工作版本,基於perl
該版本停止工作(顯然是由於 perl 版本更改)。現在我正在嘗試使用tr
和等標準實用程式sed
來替換該線路。我遇到了一些麻煩,因為要貼上的字串可能包含任意字符,包括反斜線等。
有沒有一種使用標準工具的安全方法?我發現的該問題的其他問題是已知要貼上的文本的特定解決方案。
答案1
如果您有 GNU 版本的 sed,您應該可以使用該r
命令從檔案中讀取和插入新內容,然後刪除標記行,例如
sed '/%SUBSTITUTE%/{
r path/to/newcontent
d
}' file
如果您想保留%SUBSTITUTE%
標記後插入,這很棘手,因為無論你做什麼,GNUr
擴展都會將文件內容排隊,直到結尾當前模式週期的(保留它前只需刪除該d
命令即可)。可能最簡單的方法是將其附加到文件中newcontent
:您可以像這樣即時執行此操作
sed '/%SUBSTITUTE%/{
r /dev/stdin
d
}' file < <(sed '$a %SUBSTITUTE%' path/to/newcontent)
採用完全不同的方法,您可以拆分第一個文件%SUBSTITUTE%
,然後添加新內容
csplit -s file '/%SUBSTITUTE%/'
cat xx00 newcontent xx01
您還可以read
對第一個文件的行執行 bash 循環,並在匹配標記字串時捕獲新的內容文件 - 然而,我已經因為在這個論壇上建議讀取循環進行文本處理而感到緊張。不幸的是,兩者都沒有提供就地解決方案。
答案2
這是另一種使用方法ed
。在標記之前
插入 的全部內容(即在包含 的行之前):FILE
%SUBSTITUTE%
ed -s originalfile <<< $'/%SUBSTITUTE%/- r FILE\nw\nq'
其中:
/%SUBSTITUTE%/
: 在第一行匹配處設定地址%SUBSTITUTE%
-
或: 在: : 寫入-1
之前偏移地址一行(替換為僅打印內容而不是寫入): 退出編輯器
r FILE
Reads FILE to after the addressed line.
w
originalfile
,p
q
替換FILE
為將在標記之前!echo "$TEXT"
插入 的內容:$TEXT
export TEXT
ed -s originalfile <<'IN'
/%SUBSTITUTE%/-1 r !echo "$TEXT"
w
q
IN
答案3
我基於以下找到了解決方案awk
:
text=`cat "filepaste"`
export text;
<"$file" awk '
BEGIN {REPLACE=ENVIRON["text"] "\n%SUBSTITUTE%" }
{gsub(/^%SUBSTITUTE%$/, REPLACE); print}
'
這裡「filepaste」包含要替換的內容%SUBSTITUTE%
。一個優點是可以使用不同的 shell 工具對該字串進行操作,而無需將其保存回檔案。從環境變數中讀取awk
變數REPLACE
可以避免擴展 中的轉義字元text
。
答案4
既然您有 Perl 解決方案,那麼這裡還有另一個。我用來rep.txt
存儲替換:
$ perl -pe '$re=`cat rep.txt`; chomp($re); s/%SUBSTITUTE%\n/$re/' file.txt
foo
bar
multi
line
string
foo
讀取目標檔案的每一行 ( file.txt
),然後將給定的腳本套用-e
到它並列印 ( -p
)。