【问题标题】:Sed string replace using environment variable使用环境变量替换 Sed 字符串
【发布时间】:2018-09-13 15:33:50
【问题描述】:

我有一种情况,在环境中设置了变量,我必须用它的值替换文件中的那些变量。

例如,我设置了很多变量,其中很少有 FRUIT=APPLE、TIME=DAILY。文本文件的内容是

$$FRUIT$$ 对健康有益。每个人都应该吃 $$FRUIT$$ $$TIMES$$。

现在我想要一个 sed 命令来搜索 $$$$ 中的任何字符串,并将其用作 env 变量来获取值并在文件中替换它。

苹果对健康有益。每个人都应该每天吃苹果。

我尝试了sed -i -E "s|$$([A-Z]+)$$|${\1}|g" test.txt 和其他多种组合,但它不起作用。

它给了我错误-bash: s|$$([A-Z]+)$$|${\1}|g: bad substitution

【问题讨论】:

    标签: bash sed


    【解决方案1】:

    这从How can I interpret variables on the fly in the shell script? 的答案中窃取——这个问题与那个问题并不完全重复。

    假设变量是环境的一部分:

    export FRUIT="APPLE"
    export TIMES="DAILY"
    

    您可以使用envsubst GNU 工具来执行变量替换:

    echo 'The $$FRUIT$$ is good for health. Everyone should eat $$FRUIT$$ $$TIMES$$.' | sed -E 's/\$\$([A-Z]+)\$\$/${\1}/g' | envsubst
    The APPLE is good for health. Everyone should eat APPLE DAILY.
    

    请注意,您需要在 $ 字符之前放置一个反斜杠,因为该字符对 sed 有意义。

    【讨论】:

      【解决方案2】:

      这窃取了我对How can I interpret variables on the fly in the shell script? 的回答——这个问题完全与那个问题的重复。

      str='The $$FRUIT$$ is good for health. Everyone should eat $$FRUIT$$ $$TIMES$$'
      FRUIT=APPLE
      TIMES=DAILY
      
      while [[ $str =~ ('$$'([[:alnum:]_]+)'$$') ]]; do
          str=${str//${BASH_REMATCH[1]}/${!BASH_REMATCH[2]}}
      done
      
      echo "$str"
      
      The APPLE is good for health. Everyone should eat APPLE DAILY
      

      我们搜索模板字符串,捕获带有美元符号的整个字符串,并且只捕获其中的变量名。然后我们使用shell参数扩展将匹配的模板字符串替换为变量的,使用间接变量扩展

      【讨论】:

        【解决方案3】:

        以下是仅使用 sedgrep 的方法

        list=$(grep -wo "\\$\S\S*\\$" test2 | sort -u | tr '$' '\n');
        for thing in ${list[@]}; do sed -i 's/\$\$'$thing'\$\$/'$"${!thing}"'/g' test2; done
        

        以下是一些解释(不言自明)

        user$ echo $TIMES
        DAILY
        user$ echo $FRUIT
        APPLE
        user$ cat test2 
        The $$FRUIT$$ is good for health. Everyone should eat $$FRUIT$$ $$TIMES$$.
        user$ list=$(grep -wo "\\$\S\S*\\$" test2 | sort -u | tr '$' '\n'); 
        user$ echo $list
        FRUIT TIMES
        user$ for thing in ${list[@]}; do sed -i 's/\$\$'$thing'\$\$/'$"${!thing}"'/g' test2; done
        user$ cat test2 
        The APPLE is good for health. Everyone should eat APPLE DAILY.
        

        【讨论】:

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