我正在编写一个脚本来重新格式化一些文件。除了替换现有内容的内容包含换行符之外,细节并不重要。 Sed 将换行符解释为终止 sed 命令并返回错误。我首先在 Windows 上的 gitbash 中进行了尝试,然后在 CentOS 7 上进行了尝试。下面的输出显示,一旦换行符出现在输入文件中,sed 命令就会失败。
$ echo foobar > foobar.txt
$ echo foo | sed "s/foo/$(cat foobar.txt)/"
foobar
$ echo barfoo >> foobar.txt
$ cat foobar.txt
foobar
barfoo
$ echo foo | sed "s/foo/$(cat foobar.txt)/"
sed: -e expression #1, char 12: unterminated `s' command
我希望输出是
foobar
barfoo
有没有一种简单的方法(黑客很好 - 这不适用于生产)将换行符转换为\n
或以其他方式转义它们?
答案1
escaped_file_contents=$(<foobar.txt sed 's:[\/&]:\\&:g;$!s/$/\\/')
sed "s/foo/$escaped_file_contents/g"
但请注意,尾随空行(foobar.txt
如果有)会被删除。
看到这个类似问答了解详情。
或者与perl
:
REPL=$(cat foobar.txt) perl -pe 's/foo/$ENV{REPL}/g'
或者自行perl
阅读内容:foobar.txt
perl -pe '
BEGIN {$/ = undef; $repl = <>; $_ = "\n"; chomp $repl}
s/foo/$repl/g' foobar.txt -
答案2
使用 Gnu sed 您可以执行如下操作:
$ echo foo | sed -e 's/foo/cat foobar.txt/e'
需要注意的是,当使用 s///e 命令时,sed 在完整的模式空间上进行操作。尾随的换行符也应被修剪。
或者,使用 Perl :
$ perl -lpe 's/foo/qx(cat foobar.txt)/e'