ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

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

有关处理带有斜线的值的常见相关问题,请参阅 stackoverflow.com/questions/5864146/use-slashes-in-sed-replace
这回答了你的问题了吗? Difference between single and double quotes in Bash

o
oguz ismail

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

尝试:

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

成绩单:

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

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


我不想加上引号。我想用另一个数字代替一个数字
paxdiablo: set 也不是必需的(你打算如何使用它?)。只需 replace=987654321
我通常总是使用 export 来确保为孩子设置变量,但正如你所说,你可以很容易地避免它。但是,这里是否使用 export 无关紧要(样式问题),并且对实际答案没有影响,即如何在 sed 命令中使用变量。
此解决方案似乎不适用于 -i 选项。你知道为什么吗?或者如何使它工作?
也许还指出从单引号切换到双引号需要使用反斜杠对 sed 脚本中的任何 $` 进行转义,以保护它免受 shell 对双引号字符串的替换机制的影响。
g
ghostdog74

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

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

可能想提一下这是特定于 bash 的(和 ksh?)。对大多数人来说可能并不重要,但我们中的一些人仍然被迫在古代 UNIXen 上工作:-)
请注意,这在 dash 上也会失败,这在许多现代 Linux 上是 /bin/sh
为什么在“var”之后需要两个正斜杠?根据我的测试,一个应该足够了。
如果要全局替换,而不是第一个实例,则需要斜线。
b
bob

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

# 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

N
Nicolae Iotu

找到一个 graceful solution

echo ${LINE//12345678/$replace}

感谢您分享有用的教程:)
D
Dave

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

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

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

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


这有一个问题,即在任何引号之外使用 $replace 将导致 shell 对值执行空白标记化和通配符扩展。这似乎适用于简单的值,但可能会在非平凡的字符串上显着爆炸。不要在生产代码中使用它。
M
Md. Shahariar Hossen

让我举两个例子。

使用 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

希望对您有所帮助!


M
Matthieu Moy

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

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

R
RSX

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

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

T
Tunde Pizzle

改用这个

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

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


P
Prasad Khode

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

所以使用双引号。

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

这与 Dave 的 answer 有什么不同吗?