【问题标题】:SED substitution for variableSED 替换变量
【发布时间】:2010-09-14 18:54:51
【问题描述】:

我有一个名为 check.txt 的文件,其内容如下:

$ cat check.txt
~/bin/tibemsadmin -server $URL-user $USER -password $PASWRD
$

我有一个主脚本,其中 $URL、$USER、$PASWRD 的值是从主脚本中获取的。我想使用 SED 实用程序将 $URL、$USER、$PASWRD 替换为 check.txt 中的实际值。

我正在尝试这样但它失败了。

emsurl=tcp://myserver:3243
emsuser=test
emspasswd=new
sed s/$URL/${emsurl}/g check.txt >> check_new.txt
sed s/$USER/${emsuser}/g check.txt_new.txt >> check_new_1.txt
sed s/PASWRD/${emspasswd}/g check_new_1.txt >> final.txt

我的 final.txt 输出如下所示:

~/bin/tibemsadmin -server tcp://myserver:3243 -user test -password new

你能帮帮我吗?

【问题讨论】:

    标签: sed substitution


    【解决方案1】:

    您必须非常小心地使用引号。您还需要学习如何一次完成多个操作,和/或如何使用管道。

    emsurl=tcp://myserver:3243
    emsuser=test
    emspasswd=new
    sed -e "s%\$URL%${emsurl}%g" \
        -e "s%\$USER%${emsuser}%g" \
        -e "s%\$PASWRD%${emspasswd}%g" check.txt >final.txt
    

    您的问题是 shell 在您的命令行中扩展了“$URL”(可能什么都没有),这意味着 sed 看到的不是您想要的。通过使用\ 转义$sed 可以看到您的意图。

    请注意,我最初在替换操作中使用/ 作为分隔符;但是,正如DarkDust 正确指出的那样,由于 URL 中有斜杠,所以这不起作用。我的正常后备字符是% - 如现在所示 - 但它可能出现在某些 URL 中并且可能不合适。如果我需要担心这一点,我可能会使用控制字符,例如 control-A - 或者我会使用 Perl,它可以播放而不会感到困惑。

    您还可以将三个单独的-e 表达式组合成一个,用分号代替它们。但是,我更喜欢清晰分离的三个操作。

    【讨论】:

    • 你需要选择不同的分隔符,/用于替换文本。
    • 亲爱的 Jon、DarkDust 和 Steve。非常感谢你的帮助。我现在明白我哪里错了。非常感谢。
    【解决方案2】:

    您可以通过如下修改主脚本来采取稍微不同的方法:-

    export URL="tcp://myserver:3243"
    export USER=test
    export PASWRD=new
    . ./check.txt
    

    这会设置变量,然后在主脚本的上下文中运行 check.txt

    【讨论】:

    • +1 表示开箱即用 - 但不能帮助他学习如何正确使用 sed。他还需要升级脚本以处理未设置的变量(${URL:?} 作为基本最低要求)。另外,不需要使用. ./check.txt;如果变量被导出,它可以简单地以./check.txtsh check.txt 运行。如果只是设置变量,则需要. 命令。
    【解决方案3】:

    虽然你没有说什么是失败的,但我想我看到了问题。

    我建议你这样做:

    sed "s|\$URL|${emsurl}|g"
    

    也就是说,第一个 $ 需要被转义,因为你确实想要它。然后,而不是/,我建议您使用|(管道)作为分隔符,因为它没有在您的字符串中使用。最后,使用" 确保内容被shell 解释为字符串。

    然后,您可以将所有内容通过管道连接在一起,从而不需要任何临时文件:

    sed "s|\$URL|${emsurl}|g" | sed "s|\$USER|${emsuser}|g" | sed "s|\$PASSWRD|${emspasswd}|g"
    

    【讨论】:

    • 您可以通过使用重复的“-e”选项在一个 sed 命令中完成所有操作,这样效率更高。但是使用管道比使用显式中间文件(原始文件中没有清理)更可取。
    【解决方案4】:

    变量替换应该在 sed 表达式之外并且 '$' 应该被转义;在你的情况下是这样的:

    sed -e 's/\$URL/'$emsurl'/g' -e 's/\$USER/'$emsuser'/g' -e 's/\$PASSWORD/'$emaspasswd'/g'
    

    无论如何,我会避免使用 $ 来匹配模板文件中的占位符,因为它会导致与 BASH 变量混淆,请改用不同的模式(例如 @URL@)。

    【讨论】:

      猜你喜欢
      • 2011-12-02
      • 2021-11-20
      • 2013-12-30
      • 2016-10-06
      • 1970-01-01
      • 1970-01-01
      • 2014-01-09
      • 2021-05-21
      • 2018-07-28
      相关资源
      最近更新 更多