使用SED替换长字符串 - 但在正则表达式中得到未终止的替换

问题描述 投票:0回答:2

您想尝试用长的字符串替换以下字符串:

@x@ 

我从命令行获得的字符串:

read test    
sed -i --backup 's/@x@/'${test}'/g' file.json README.md

但它只适用于1个单词,如果单词之间有空格则无效。甚至在报价之间

sed: 1: "s/@x@/string test string: unterminated substitute in regular expression
linux macos sed quoting
2个回答
0
投票

sed不理解字符串是一系列文字字符的字符串。它将一个正则表达式(不是字符串)替换为一组分隔符中的反向引用“字符串”(也不是字符串)(这也需要在正则表达式和替换中仔细处理)。有关更多信息,请参阅Is it possible to escape regex metacharacters reliably with sed

要用另一个字符串替换字符串,最简单的方法是使用一个理解字符串的工具,例如awk:

$ cat file
before stuff
foo @x@ bar
after stuff

$ cat tst.awk
BEGIN {
    old = ARGV[1]
    new = ARGV[2]
    ARGV[1] = ARGV[2] = ""
}
s = index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+length(old)) }
{ print }

$ test='a/\t/&"b'

$ awk -f tst.awk '@x@' "$test" file
before stuff
foo a/\t/&"b bar
after stuff

无论test包含哪些字符,甚至换行符,上述内容都会有效:

$ test='contains a
newline'
$ awk -f tst.awk '@x@' "$test" file
before stuff
foo contains a
newline bar
after stuff

0
投票

问题源于您使用单引号的方式。目前,您正在终止2.单引号后面的输入。请参阅错误消息,它会让您意识到它缺少某些内容。

如果您有一个包含以下内容的文件:

foo @x@ foo

比你可以替换内容,例如使用以下命令:

sed 's/@x@/bar foo bar/' foo.txt > foo2.txt

得到:

foo bar foo bar foo

如果你需要传递一个变量,Gordon Davisson的评论会告诉你正确的方法。

顺便说一句,如果你想使用inplace选项,在我的linux上你需要使用这样的命令:

sed -i.old "s/@x@/${test}/" foo.txt

但我认为这可能取决于你的环境(mac?)。

© www.soinside.com 2019 - 2024. All rights reserved.