【问题标题】:Sed - replacing a string with a variable full of weird charactersSed - 用一个充满奇怪字符的变量替换字符串
【发布时间】:2014-02-27 09:25:42
【问题描述】:

我正在使用 sed 将文件中的字符替换为变量。这个变量基本上是读取文件或网页的内容,其中包含多个类似下面的哈希字符串,这些字符串是随机生成的:

define('AUTH_KEY',         'CVo|BO;Qt1B|+GE}+h2/yU7h=5`/wRV{>%h.b_;s%S8-p|>qpf]|/Vf@`&[g~*:&');
define('SECURE_AUTH_KEY',  '{G2-<^jWRd7]2,?]6hhM^*asg.2C.+k=gf33-m+ZK_{Mt|q*<ELF4|gPjyxtTh!)');
define('LOGGED_IN_KEY',    'jSNo9Z;5d]tzZoh-QQ`{M-&~y??$R({:*m`0={67=+mF?L.e+R{;)+4}qCAAHz=C');
define('NONCE_KEY',        '19Vt4=%8j/Z-&~ni0S<]9)J^~sy9dh|h9M_RX2#K0]F9+.v+[BP1d&B&}-FTKIJ,');
define('AUTH_SALT',        'jr7f?T|@Cbo]XVAo}N^ilkvD>dC-rr]5{al64|?_Hz }JG$yEi:_aU )Olp YAD+');
define('SECURE_AUTH_SALT', 'hm#Z%O!X_mr?lM|>>~r-?F%wi R($}|9R[):4^NTsj+gS[qnv}7|+0<9e-$DJjju');
define('LOGGED_IN_SALT',   'tyPHBOCkXZh_4H;G|^.&|^#JPB/f;{}y_Orj!6AH?@wovx+KKtTZ A[HMS9SZJ|N');
define('NONCE_SALT',       'Eb-/t 5D-vPV9I--8F<[^lcherGv.g+|7p6;+xP|5g6P}tup1K.vuHAQ=uWZ#}H^');

变量定义如下:

KEY=$(cat keyfile)

我使用了以下 sed 语法:

sed -i "s/stringtoreplace/$KEY/" /path/to/file

我也尝试了不同的变体,使用单引号,变量周围的引号

sed -i "s/stringtoreplace/"$KEY"/" /path/to/file

sed -i "s/stringtoreplace/"${KEY}"/" /path/to/file

sed -i "s/stringtoreplace/'$KEY'/" /path/to/file

我认为我以各种可能的方式“蛮力”加引号,但我不知道如何转义这些随机生成的字符。我不断收到以下错误:

未终止的s 命令

关于如何用类似奇怪的散列变量替换字符串有什么建议吗?

【问题讨论】:

标签: bash variables unix sed escaping


【解决方案1】:

试试这个:

KEY=$(cat keyfile | sed -e 's/[]\/()$*.^|[]/\\&/g')
sed -i "s/stringtoreplace/$KEY/" /path/to/file

【讨论】:

    【解决方案2】:

    问题在于 $KEY 变量包含斜杠,这是s 命令的分隔符。

    sed 可以做的不仅仅是搜索和替换:

    sed '/stringtoreplace/{
         d
         r keyfile
    }' /path/to/file
    

    我假设“stringtoreplace”单独出现在一行上。

    【讨论】:

    • OP - 如果斜杠是问题所在,那么您可以为 sed 使用不同的分隔符。 sed 使用跟在首字母 's' 后面的任何字符作为分隔符——人们只是使用 / 作为标准。是否有保证不会出现在您的哈希中的特殊字符?如果是这样,您可以使用(例如,冒号)'s:stringtoreplace:${KEY}:'
    • @Kevin,如果问题中指出的数据是随机的,那么您永远不会知道哪些分隔符是安全的。
    • 我建议仅当 OP 可以确定生成字符串的函数以及是否有任何无法由该函数创建的可打印字符时才使用该方法。这个方向可能比它的价值更多。
    【解决方案3】:

    一种可能性是使用 bash 代替 sed。这使得替换很容易,但您必须模拟 -i 选项。

    类似这样的:

    TMPFILE=$(mktemp)
    KEY=$(cat keyfile)
    while IFS= read -r LINE; do
      echo "${LINE//stringtoreplace/$KEY}"
    done </path/to/file >$TMPFILE
    mv $TMPFILE /path/to/file
    

    【讨论】:

      【解决方案4】:

      sed 是在单行上进行简单替换的出色工具,但对于其他任何内容,您都应该使用 awk:

      awk -v key="$KEY" '{sub(/stringtoreplace/,key)}1' file
      

      无论“$KEY”包含什么字符,除了“&”之外,这将起作用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-12
        • 2021-09-28
        • 2015-04-18
        • 2021-07-04
        • 2017-06-29
        • 1970-01-01
        相关资源
        最近更新 更多