我想将file1.txt中的标记(REPLACETHIS)替换为file2.txt的全部内容,其中包括换行符和特殊字符。
file2.txt内容的一个例子是
<Location />
Order deny,allow
Deny from all
Allow from 1.2.3.4
Allow from 5.6.7.8
</Location>
我的通用代码,减去特殊字符的处理,看起来像这样:
value=$(</home/name/scripts/file2.txt)
sed -i -e "s|REPLACETHIS|$value|" /home/name/scripts/file1.txt
处理此问题的最佳方法是什么?
答案 0 :(得分:2)
在sed
中,从文件插入文本的最佳选择是使用r file
命令:
sed -i -e '/REPLACETHIS/{r /path/to/file2.txt' -e ';d;}' file1.txt
或者,在扩展形式中:
sed -i '/REPLACETHIS/ {
r /path/to/file2.txt
d
}' file1.txt
r file
命令将读取file
中的文本并将其插入输出流。要删除REPLACETHIS
文本,我们还需要删除d
命令(抬头:这将删除包含文本REPLACETHIS
的完整行;如果您需要使用中间文本标记,您可以将d
替换为s///
,如@ghoti所述。
在第一个示例中,我们不得不在两个表达式中打破sed
程序,原因是r command
必须以换行符结束。另一种方法是将程序编写成几行,如扩展示例所示。
另请注意,BSD sed
处理-i
选项的方式与GNU sed
不同。以上内容适用于GNU,但如果你需要它用于BSD,你应该写:-i ''
而不是-i
。
答案 1 :(得分:0)
根本不需要使用sed
。
file_to_change=/home/name/scripts/file1.txt
value=$(</home/name/scripts/file2.txt)
infile=$(<"$file_to_change")
tempfile=$(mktemp "$file_to_change.XXXXXX")
if printf '%s\n' "${infile//REPLACETHIS/$value}" >"$tempfile"; then
mv -- "$tempfile" "$file_to_change"
else
rm -f -- "$tempfile"
fi
即使没有sed -i
(这是非标准的,不可移植的,并且在常见实现之间不兼容),这仍然有效。