【问题标题】:Bash. Replace with sed. End of line problem重击。替换为 sed。行尾问题
【发布时间】:2019-05-23 18:35:57
【问题描述】:

我正在尝试使用 sed 在文件中搜索和替换。但是 sed 似乎讨厌行尾特殊字符。

text=$(shuf text.txt)
echo "This is text:
$text"
sed -i "s~%text%~$text~g" t.txt

这是我得到的:

This is text:
 line 2
 line 1
 line 3
 line 4
sed: -e expression #1, char 15: unterminated `s' command

我尝试将 \n 替换为 \r,但结果并不令人满意。 有一个选项可以执行 tr '\n' , '$' 然后再向后执行,但它似乎不正确。

帮助?

【问题讨论】:

  • sed 命令以换行符结尾。换行符是sed 内的命令分隔符。所以s~blabla\n 被 sed 解释为单个命令。 but it doesn't seems right. - 这实际上是一个非常好的主意,我会说去吧。为了更加安全,请使用不可读的字符,例如 tr '\n' $'\01'
  • 谢谢。那么有没有办法避免tr呢?
  • 更好的方法是遇到%text%时读取文件内容。另请注意,sed 将解析 \r \n 等在 $text 中并替换它们,因此您可能会遇到“\”问题。有时这也可以通过另一个转义 sed 来解决...sed 's@%text%@$(<<<"$text" sed 's#\\#\\\\#g')/.... 但是,一如既往,awk 解决方案看起来很整洁。

标签: bash sed substitution end-of-line


【解决方案1】:

使用 sed 和 bash

既然你用的是bash,那就试试吧:

sed -i "s~%text%~${text//$'\n'/\\n}~g" t.txt

${text//$'\n'/\\n} 是 bash 的 模式替换 的一个示例。 在这种情况下,它将所有换行符替换为反斜杠,后跟nsed 将解释为换行符。

示例

考虑这个text 变量:

$ echo "$text"
line 2
 line 1
 line 3
 line 4

还有这个输入文件:

$ cat t.txt
start
%text%
end

现在,运行我们的命令:

$ sed "s~%text%~${text//$'\n'/\\n}~g" t.txt
start
line 2
 line 1
 line 3
 line 4
end

当然,要就地更改文件,请添加 -i 选项。

使用 awk

使用与上述相同的text 变量和t.txt 文件:

$ awk -v new="$text" '{gsub(/%text%/, new)} 1' t.txt
start
line 2
 line 1
 line 3
 line 4
end

【讨论】:

  • 谢谢!十分优雅。 :)
猜你喜欢
  • 1970-01-01
  • 2023-02-15
  • 1970-01-01
  • 1970-01-01
  • 2010-11-29
  • 2019-11-16
  • 1970-01-01
  • 2021-10-21
  • 1970-01-01
相关资源
最近更新 更多