使用变量替换Shell脚本中的字符串


Answers:


146

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

尝试:

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

假设你要的报价投入如果你。想要的报价,使用:

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

文字记录:

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

只是要小心,以确保${replace}没有意义的任何字符sed(如/例如),因为它会造成混乱,除非逃脱。但是,正如您所说,如果您要用另一个替换一个数字,那应该不是问题。


我不希望使用引号。我希望用一个数字替换另一个数字
Vijay 2010年

1
paxdiablo:set也没有必要(无论如何,您将如何使用它?)。只是replace=987654321
Roman Cheplyaka

我通常总是export确保为孩子设置变量,但是,正如您所说,您可以很容易地避免使用它。但是,export此处的使用与否无关(样式问题),并且对实际答案(即如何在sed命令中使用变量)没有影响。
paxdiablo 2014年

该解决方案似乎不适用于该-i选件。你知道为什么吗?或如何使其工作?
加百利

1
也许还指出,从单一切换到双引号需要任何$`sed脚本用反斜杠进行转义,以保护它从外壳的替代机制为双引号字符串。
人间

73

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

$ var="12345678abc"
$ replace="test"
$ echo ${var//12345678/$replace}
testabc

3
可能要提到的是bash特定的(和ksh?)。也许对大多数人来说并不重要,但是我们中有些人仍然被迫从事古老的UNIXen的工作:-)
paxdiablo 2010年

6
当心,这/bin/sh在许多现代Linux 上的破折号上也失败了。
phihag 2015年

26

并非特定于该问题,而是针对那些需要相同功能的人,以便从先前的答案中清楚地了解:

# 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

8

单引号很强。进入内部之后,您将无法进行任何操作来调用变量替换,直到离开。请使用双引号代替:

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


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

您仍然可以使用单引号,但是当您希望变量在正确的位置扩展时,您必须“打开”它们。否则,该字符串是“字面意义上的”(如正确表示的@paxdiablo,他的答案也正确)


这有一个问题,即$replace在引号之外使用会导致Shell对值执行空白令牌化和通配符扩展。这似乎适用于简单的值,但在非平凡的字符串上可能会急剧膨胀。不要在生产代码中使用它。
三人房

2

为了让您的shell扩展变量,您需要使用双引号,例如

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

0

我对此有类似的要求,但我的replace var包含一个&符。这样逃避“&”号解决了我的问题:

replace="salt & pepper"
echo "pass the salt" | sed "s/salt/${replace/&/\&}/g"

-1

改用这个

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

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


-2

我更喜欢使用双引号,因为如果不能更改其中的任何内容或无法调用变量替换,则单方quptes就像我们使用它们一样非常强大。

因此请使用双引号。

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

6
这和戴夫的答案有什么不同吗?
devnull 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.