115

我正在使用以下代码替换 shell 脚本中的字符串。

echo $LINE | sed -e 's/12345678/"$replace"/g'

但它被替换为$replace而不是该变量的值。

谁能告诉我出了什么问题?

4

12 回答 12

173

如果要解释$replace,则不应使用单引号,因为它们会阻止变量替换。

尝试:

echo $LINE | sed -e "s/12345678/${replace}/g"

成绩单:

pax> export replace=987654321
pax> echo X123456789X | sed "s/123456789/${replace}/"
X987654321X
pax> _

请注意确保它${replace}没有任何重要的字符sed/例如),因为除非转义,否则它会引起混乱。但是,如果,正如你所说,你用另一个数字替换一个数字,那应该不是问题。

于 2010-07-22T05:31:34.513 回答
84

您可以使用外壳(bash/ksh)。

$ var="12345678abc"
$ replace="test"
$ echo ${var//12345678/$replace}
testabc
于 2010-07-22T05:38:22.760 回答
33

不是针对问题的,而是对于需要相同类型的功能的人,以便从以前的答案中获得清晰的扩展:

# create some variables
str="someFileName.foo"
find=".foo"
replace=".bar"
# notice the the str isn't prefixed with $
#    this is just how this feature works :/
result=${str//$find/$replace}
echo $result    
# result is: someFileName.bar

str="someFileName.sally"
find=".foo"
replace=".bar"
result=${str//$find/$replace}
echo $result    
# result is: someFileName.sally because ".foo" was not found
于 2016-06-27T22:54:57.377 回答
15

找到了一个优雅的解决方案

echo ${LINE//12345678/$replace}
于 2018-12-25T23:44:06.770 回答
9

单引号非常强大。一旦进入,在您离开之前,您无法调用变量替换。改用双引号:

echo $LINE | sed -e "s/12345678/$replace/g"
于 2011-07-20T03:59:32.383 回答
5
echo $LINE | sed -e 's/12345678/'$replace'/g'

您仍然可以使用单引号,但是当您希望变量在正确的位置展开时,您必须“打开”它们。否则字符串被“字面”采用(正如@paxdiablo 正确指出的那样,他的回答也是正确的)

于 2010-07-22T05:36:52.403 回答
2

要让您的外壳扩展变量,您需要使用双引号,例如

sed -i "s#12345678#$replace#g" file.txt

如果$replace包含特殊sed字符 ( #, \),这将中断。但是您可以预处理$replace以引用它们:

replace_quoted=$(printf '%s' "$replace" | sed 's/[#\]/\\\0/g')
sed -i "s#12345678#$replace_quoted#g" file.txt
于 2015-05-08T10:08:30.097 回答
1

让我举两个例子。

  • 使用 sed:
#!/bin/bash
LINE="12345678HI"
replace="Hello"
echo $LINE | sed -e "s/12345678/$replace/g"
  • 不使用 sed:
LINE="12345678HI"
str_to_replace="12345678"
replace_str="Hello"
result=${str//$str_to_replace/$replace_str}
echo $result

希望对您有所帮助!

于 2021-05-26T02:16:32.300 回答
0

我对此有类似的要求,但我的替换变量包含一个&符号。像这样逃避&符号解决了我的问题:

replace="salt & pepper"
echo "pass the salt" | sed "s/salt/${replace/&/\&}/g"
于 2020-05-06T11:01:51.390 回答
-1

改用这个

echo $LINE | sed -e 's/12345678/$replace/g'

这对我有用,只需删除引号

于 2017-09-26T16:24:48.417 回答
-1

与问题无关,但如果有人将字符串作为参数传递给 bash 脚本,这可能会有所帮助。

采用:

./bash_script.sh "path\to\file"

代替:

./bash_script.sh path\to\file

供您参考

于 2020-11-23T13:29:29.753 回答
-2

我更喜欢使用双引号,因为单个 quptes 非常强大,因为如果不能更改其中的任何内容或可以调用变量替换,我们会使用它们。

所以使用双引号。

echo $LINE | sed -e "s/12345678/$replace/g"
于 2014-01-03T06:00:31.573 回答