Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 使用SED替换长字符串-但在正则表达式中得到了未终止的替换_Linux_Macos_Sed_Quoting - Fatal编程技术网

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

Linux 使用SED替换长字符串-但在正则表达式中得到了未终止的替换,linux,macos,sed,quoting,Linux,Macos,Sed,Quoting,hi正在尝试用长字符串替换以下字符串: @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 问题源于您使用单引号的方式。当前,您正在

hi正在尝试用长字符串替换以下字符串:

@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

问题源于您使用单引号的方式。当前,您正在终止2后面的输入。单引号。看到错误消息,它会让您意识到它丢失了一些东西

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

foo @x@ foo
然后,您可以替换内容,例如,使用以下命令:

sed 's/@x@/bar foo bar/' foo.txt > foo2.txt
并获得:

foo bar foo bar foo
如果需要传入变量,Gordon Davisson的注释会告诉您正确的方法

顺便说一下,如果您想使用inplace选项,在my linux上,您需要使用如下命令:

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

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

问题源于您使用单引号的方式。当前,您正在终止2后面的输入。单引号。看到错误消息,它会让您意识到它丢失了一些东西

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

foo @x@ foo
然后,您可以替换内容,例如,使用以下命令:

sed 's/@x@/bar foo bar/' foo.txt > foo2.txt
并获得:

foo bar foo bar foo
如果需要传入变量,Gordon Davisson的注释会告诉您正确的方法

顺便说一下,如果您想使用inplace选项,在my linux上,您需要使用如下命令:

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

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

sed不理解字符串,其中字符串是一系列文字字符。它将regexp(不是字符串)替换为启用反向引用的“字符串”(也不是字符串),所有这些都在一组分隔符内(这也需要在regexp和替换中小心处理)。有关更多信息,请参阅

要用另一个字符串替换字符串,最简单的方法是只使用理解字符串的工具,如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

sed不理解字符串,其中字符串是一系列文字字符。它将regexp(不是字符串)替换为启用反向引用的“字符串”(也不是字符串),所有这些都在一组分隔符内(这也需要在regexp和替换中小心处理)。有关更多信息,请参阅

要用另一个字符串替换字符串,最简单的方法是只使用理解字符串的工具,如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

如果您在MacOS上运行它,并且遇到了“正则表达式中的未终止替换”,则有一个更简单的解释:

MacOS的sed版本与linux上的版本稍有不同<代码>-i需要一个参数。如果没有,只需在
-i

sed -i "" --backup 's/@x@/'${test}'/g' file.json README.md
或者,如果您只需要删除dome line,这在linux上可以正常工作,但在MacOS上会出现“无效命令代码”

sed -i 39d filenamehere.log
这在MacOS上有效

sed -i "" 39d filenamehere.log

如果您在MacOS上运行它,并且遇到了“正则表达式中的未终止替换”,则有一个更简单的解释:

MacOS的sed版本与linux上的版本稍有不同<代码>-i需要一个参数。如果没有,只需在
-i

sed -i "" --backup 's/@x@/'${test}'/g' file.json README.md
或者,如果您只需要删除dome line,这在linux上可以正常工作,但在MacOS上会出现“无效命令代码”

sed -i 39d filenamehere.log
这在MacOS上有效

sed -i "" 39d filenamehere.log

但是我不发送带引号的字符串。引号不是唯一的潜在问题,还有
/
s、
&
s、
\
s等等。一旦您解决了引号问题,您仍然有一个问题,即您无法使用sed用任何字符串替换regexp。有关预处理替换字符串所需的内容,请参见。wrt
单引号。。。需要转义或删除。
-不需要。不能在单引号分隔的字符串/脚本中转义单引号,将脚本括在单引号中是正确的,但可以打开一个部分,让shell解释它,例如展开变量。OPs引用错误只是没有重复引用变量-
's/@x@/'${test}'/g'
。当然,正如我在其他评论和回答中提到的,还有其他问题。另外,wrt UNIX变体—AFAIK Mac运行BSD UNIX变体,而不是linux UNIX变体。但我不发送带引号的字符串。引号不是唯一的潜在问题,
/
s、
&
s、
\
s等等。一旦您解决了引号问题,您仍然有一个问题,即您无法使用sed用任何字符串替换regexp。有关预处理替换字符串所需的内容,请参见。wrt
单引号。。。需要转义或删除。
-不需要。不能在单引号分隔的字符串/脚本中转义单引号,将脚本括在单引号中是正确的,但可以打开一个部分,让shell解释它,例如展开变量。OPs引用错误只是没有重复引用变量-
's/@x@/'${test}'/g'
。当然,正如我在其他评论和回答中提到的,还有其他问题。另外,wrt UNIX变体-AFAIK Mac运行BSD UNIX变体,而不是linux UNIX变体。变量引用应始终使用双引号,以避免类似问题。使用类似于
sed-i--backup's/@x@/''${test}'/g'file.json README.md
或只使用
sed-i--backup“s/@x@/${test}/g”file.json README.md
。善于发现像这样的常见问题。此外,您应该添加一些健全性检查,以便嵌入的变量不包含将成为interp的字符