用sed替换多行的单词?

Cob*_*ast 27 bash replace sed

我正在研究一个bash脚本,它必须准备一封电子邮件发送给用户.

它汇总了一些数据,最终会产生多行内容.对于存储的示例$DATA.

现在,经过一些stfw我找到了一些类似的东西,sed -ei "s/_data_/${DATA}/g" mail.tpl并且还用多行替换变量.他们都没有工作.

现在问题是,如何sed用多行文本替换某些内容?

(sed也欢迎替代品!)

rin*_*rer 16

如果用" \n"s 构建多行文本,这将使用一个简单的sed命令:

DATA=`echo ${DATA} | tr '\n' "\\n"`
#now, DATA="line1\nline2\nline3"
sed "s/_data_/${DATA}/" mail.tpl
Run Code Online (Sandbox Code Playgroud)

  • 再看一遍,我认为没有*任何*版本的`tr`可以替换一个带有两个字符的字符; 这只是这项工作的错误工具.由于你错误地没有将参数引用到"echo",因此新行会意外丢失,但这会产生多种其他不良副作用; 并且`tr`在这里根本不做任何事.**这不应该是公认的答案.** (6认同)
  • 我从那个方法得到`sed: -e expression #1, char 32: unterminated 's' command`。 (5认同)
  • 这并不完全是可移植的;并非所有“sed”方言都接受“\n”二合字母来表示文字换行符。在其他一些方言中,您可能需要在文字换行符之前使用反斜杠。本页上的其他答案向您展示了如何更详细地执行此操作。 (2认同)

Ken*_*ent 13

AWK?

foo
bar
blah _data_and_data_
foo
_data_ foobar _data_ again
Run Code Online (Sandbox Code Playgroud)

  • 显然有些(?)awks 会不喜欢这个并说“字符串中的换行符”(尽管在“DATA”周围没有双引号的答案将以不同的方式失败)。 (3认同)
  • 哦,天哪,这工作!希望我能再给您+1次,您救了我! (2认同)
  • 嘿肯特,这是一个旧的,但你似乎缺少$ DATA周围的报价.确认? (2认同)
  • 确实应该添加引号: awk -vr="$DATA" '{gsub(/_data_/,r)}1' test (2认同)

小智 11

我试过了,sed 's/pattern/\na\nb\nc/g'但它并不适用于所有系统.什么工作是\在替换模式中添加一个换行符,如下所示:

sed 's/pattern/a\
b\
c/g'
Run Code Online (Sandbox Code Playgroud)

这会附加一行,其中包含b一个包含c模式的行.

要将它放在变量中,请使用双反斜杠:

export DATA="\\
a\\
b\\
c"
Run Code Online (Sandbox Code Playgroud)

然后:

sed "s/pattern/${DATA}/g"
Run Code Online (Sandbox Code Playgroud)

请注意双引号.


anu*_*ava 11

我建议简单地用perl命令替换sed,如下所示:

perl -i.bak -pe 's/_data_/$ENV{"DATA"}/g' mail.tpl 
Run Code Online (Sandbox Code Playgroud)

  • 这是唯一在 OSX 上对我有用的。所有其他基于 sed 和 awk 的方法对我来说都失败了。 (2认同)
  • 如果DATA包含斜杠,将无法解决问题。但是您可以`导出DATA`并以$ ENV {“ DATA”}`的形式从Perl内部访问它,而不会混淆代码和数据。所以`'s / _data _ / $ ENV {“ DATA”} / g'`很简单。 (2认同)

Yuv*_*val 9

戒指持有人的回答对我不起作用; 我认为tr那里的用法是错误的,而且它的编写方式,它只是通过使用来删除换行符echo.

相反,我用过sed.我使用另一个答案的代码来替换换行符(信用:Zsolt Botykai).我也期望$在我的输入中有一些美元符号(),所以我也照顾好了.您可能需要添加其他输入处理.请注意使用双引号echo来保留换行符.

DATA="$(cat whatever)"
ESCAPED_DATA="$(echo "${DATA}" | sed ':a;N;$!ba;s/\n/\\n/g' | sed 's/\$/\\$/g')"
Run Code Online (Sandbox Code Playgroud)

然后你可以使用${ESCAPED_DATA}sed:

cat input | sed 's/one liner/'"${ESCAPED_DATA}"'/' > output 
Run Code Online (Sandbox Code Playgroud)

只是想我会分享.


Ben*_*ley 7

将变量回显到临时文本文件中。

将文本文件插入到 mail.tpl 并从 mail.tpl 中删除数据

echo ${DATA} > temp.txt    
sed -i -e "/_data_/r temp.txt" -e "//d" mail.tpl
Run Code Online (Sandbox Code Playgroud)


小智 5

\用 a (除了最后一个)转义所有换行符对我有用。最后一个换行符不得被转义,以免破坏s命令。

例子 :

DATA="a
b
c"

ESCAPED=$(echo "${DATA}" | sed '$!s@$@\\@g')
echo "${ESCAPED}" 
a\
b\
c

sed "s/pattern/${ESCAPED}/" file
Run Code Online (Sandbox Code Playgroud)