如何在 sed 替换的 LHS 和 RHS 中使用变量?

Mic*_*ant 66 sed

我想要做:

cat update_via_sed.sh | sed 's/old_name/new_name/' > new_update_via_sed.sh
Run Code Online (Sandbox Code Playgroud)

在我的程序中。

但我想使用变量,例如

old_run='old_name_952'
new_run='old_name_953'
Run Code Online (Sandbox Code Playgroud)

我试过使用它们,但没有发生替换(没有错误)。我试过了:

cat update_via_sed.sh | sed 's/old_run/new_run/'
cat update_via_sed.sh | sed 's/$old_run/$new_run/'
cat update_via_sed.sh | sed 's/${old_run}/${new_run}/'
Run Code Online (Sandbox Code Playgroud)

Sté*_*las 54

你可以这样做:

sed "s/$old_run/$new_run/" < infile > outfile
Run Code Online (Sandbox Code Playgroud)

但请注意,这$old_run将被视为正则表达式,因此变量包含的任何特殊字符,例如/.必须被转义。同样,在$new_run&\字符需要特殊处理,您必须转义其中的/和换行符。

如果$old_run或的内容$new_run不在您的控制之下,那么执行该转义至关重要,否则该代码将构成代码注入漏洞

  • 我在 sed params 中使用单引号,切换到双引号并且它工作文件。惊人的。 (3认同)

Mic*_*ant 32

这有效:

cat update_via_sed.sh | sed 's/'"$old_run"'/'"$new_run"'/'
Run Code Online (Sandbox Code Playgroud)

因为我想“重用”同一个文件,我实际上将它用于任何希望使用类似方法的人:

cat update_via_sed.sh | sed 's/'"$old_run"'/'"$new_run"'/' > new_update; mv -f new_update update_via_sed.sh
Run Code Online (Sandbox Code Playgroud)

上面创建了一个新文件然后删除当前文件而不是将新文件重命名为当前文件。

  • 您不需要 cat、mv 或额外的 '' 除非您将在其中包含特殊字符。所以它是`sed -is/"$old"/"$new"/update_via_sed.sh`。但是请注意,这不适用于任何新旧值。例如,它不能包含 / 等,因为 $old 仍然是一个搜索,而 $new 是一个替换模式,其中某些字符具有特殊含义。 (5认同)
  • `sed -i "s/$old/$new/"` 也可以(有上述注意事项)。`sed` 通常认为分隔符是 `s` 命令之后的第一个字符 - 即如果你的变量包含斜杠 `/` 但不能在 (`@`) 处说,你可以使用 "s@$old@$new @”。 (2认同)

小智 23

你可以在 sed 中使用变量,只要它是双引号(不是单引号):

sed "s/$var/r_str/g" file_name >new_file
Run Code Online (Sandbox Code Playgroud)

如果/变量中有正斜杠 ( ) 则使用不同的分隔符,如下所示

sed "s|$var|r_str|g" file_name >new_file
Run Code Online (Sandbox Code Playgroud)


Mic*_*ant 21

'就地' sed(使用 -i 标志)是答案。感谢彼得。

sed -i "s@$old@$new@" file
Run Code Online (Sandbox Code Playgroud)

  • 你在错误的地方引用了引号。引号必须围绕变量,而不是 `s@`(这对 shell 来说没有任何特殊性)。最好是将所有内容都放在引号内,例如 `sed -i "s@$old@$new@" file`。请注意,`-i` 不是标准的 `sed` 选项。 (2认同)