不要将变量内容视为sed中的特殊字符

时间:2014-03-06 14:16:53

标签: bash sed

我有以下sed命令:

sed -i "4i\ $CHANGES" ./CHANGELOG.rst

但是,我的$CHANGES变量看起来像这样:

title
-----

* list
  * elem
  * elem

因此,上述命令失败并出现以下错误:sed: -e expression #1, char 149: unknown command: '*'。我知道这是因为$CHANGES变量的内容在某种程度上被解释了,但我如何指定只将变量中的字符串用作原始字符串,而不解释其内容?

4 个答案:

答案 0 :(得分:2)

另一个好老的“使用AWK代替”风格的答案......

如果你只想在第4行插入该字符串,你可以在AWK中这样做:

awk -v var="$CHANGES" 'NR == 4 { print var } { print }' ./CHANGELOG.rst > tmp && mv tmp ./CHANGELOG.rst

这会在您的文件第4行之前插入变量$CHANGES的内容。

正如评论和elsewhere中所述,较新版本的gawk(> = 4.1.0)可以进行就地编辑:

gawk -i inplace -v var="$CHANGES" 'NR == 4 { print var } { print }' ./CHANGELOG.rst

保存几个字符。

答案 1 :(得分:2)

sed "4 i\
$CHANGES" ./CHANGELOG.rst
  • i\
  • 之后需要换行
  • i
  • 之前的某个空格上
  • $更改必须使用\
  • 转义所有新行

所以awk在这种情况下更好。另一种方法是使用带有临时文件的sed(i插入之前和r追加文件,所以之前的1行)

echo "${CHANGES}" > TempoFile
sed "3 r TempoFile" YourFile
rm TempoFile

答案 2 :(得分:2)

尝试

sed -i "4 i\
${CHANGES//$'\n'/\\$'\n'}" ./CHANGELOG.rst

正如@NeronLeVelu所说,

  • 您需要在i\
  • 之后换行
  • 传递给sed的{​​{1}}函数的文本中的换行符必须为i - 转义 - 这就是上面的bash参数(变量)替换。

答案 3 :(得分:1)

Good old ed:

$ CHANGES="title
-----

* list
  * elem
  * elem"

$ seq 10 > file

$ ed file <<END
4i
$CHANGES
.
w
q
END
21
59

$ cat file
1
2
3
title
-----

* list
  * elem
  * elem
4
5
6
7
8
9
10