使用sed插入带有特殊字符的文件的内容

时间:2017-11-07 15:27:58

标签: bash sed sh

我想将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

处理此问题的最佳方法是什么?

2 个答案:

答案 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(这是非标准的,不可移植的,并且在常见实现之间不兼容),这仍然有效。