【问题标题】:How to replace placeholder character or word in variable with value from another variable in Bash?如何用 Bash 中另一个变量的值替换变量中的占位符或单词?
【发布时间】:2012-11-22 13:05:18
【问题描述】:

我正在尝试编写一个简单的 Bash 脚本。我有一个简单的“模板”变量:

template = "my*appserver"

然后我有一个函数 (get_env()),它返回值 devqalive。我想调用get_env,然后用get_env 的返回值替换template 变量并用星号替换它。所以:

# Returns "dev"
server = get_env

# Prints "mydevappserver"
template = string_replace(server, template)

或者:

# This time, it returns "live"
server = get_env

# Prints "myliveappserver"
template = string_replace(server, template)

我应该使用什么来代替 string_replace() 函数来完成绑定?

【问题讨论】:

    标签: bash shell replace


    【解决方案1】:

    bash 脚本中的字符串替换可以例如由 sed 实现:

    template=$(echo $template | sed 's/old_string/new_string/g')
    

    这会将模板变量中的 old_string 替换为 new_string。

    【讨论】:

    • 如果我要替换很多,sed 的调用次数肯定会影响我的脚本的性能。
    【解决方案2】:

    是的,要么像其他人所说的那样'sed',要么从你的模板开始在 2 个单独的变量中并即时构建。例如

    templateprefix="my"
    templatesuffix="appserver"
    
    server=get_env
    
    template=${templateprefix}${server}${templatesuffix}
    

    【讨论】:

      【解决方案3】:

      Bash 可以自己做字符串替换:

      template='my*appserver'
      server='live'
      template="${template/\*/$server}"
      

      有关字符串替换的更多详细信息,请参阅advanced bash scripting guide

      所以对于 bash 函数:

      function string_replace {
          echo "${1/\*/$2}"
      }
      

      并使用:

      template=$(string_replace "$template" "$server")
      

      【讨论】:

      • 这个 ("${1/\*/$2}") 只替换脚本中的第一次出现:(
      • 解决方法比较简单,替换ALL出现的正确形式是"${1//\*/$2}"
      • 读者应该对指向 ABS 的链接犹豫不决。在某些地方,它是一个非常有用的资源,但它存在内容和呈现方面的问题。
      【解决方案4】:

      正如没有人提到它,这是使用printf 的一个很酷的可能性。占位符必须是%s,而不是*

      # use %s as the place-holder
      template="my%sappserver"
      
      # replace the place-holder by 'whatever-you-like':
      server="whatever-you-like"
      printf -v template "$template" "$server"
      

      完成!

      如果你想要一个函数来做到这一点(并注意所有其他提到函数的解决方案是如何使用丑陋的子外壳的):

      #!/bin/bash
      
      # This wonderful function should be called thus:
      # string_replace "replacement string" "$placeholder_string" variable_name
      string_replace() {
          printf -v $3 "$2" "$1"
      }
      
      # How to use it:
      template="my%sappserver"
      server="whatever-you-like"
      
      string_replace "$server" "$template" destination_variable
      
      echo "$destination_variable"
      

      完成(再次)!

      希望您喜欢它...现在,根据您的需要调整它!

      备注。 看来这种使用printf 的方法比bash 的字符串替换要快一些。而且这里根本没有 subshel​​l!哇,这是西方最好的方法。

      有趣。如果你喜欢有趣的东西,你可以把上面的函数string_replace写成

      string_replace() {
          printf -v "$@"
      }
      
      # but then, use as:
      string_replace destination_variable "$template" "$server"
      

      【讨论】:

        【解决方案5】:

        我需要做这样的事情,但我需要 sed 并且 replace 子句需要包含一个变量。我最终得到了这个。

        其中变量名是 $puttyline

        sed "s/\(\[remote .origin.\]\)/\1\n$puttyline/"
        

        因此 sed 搜索 [remote "origin"] 并记住匹配项,并在其后插入一行,其中包含变量 $puttyline 中的任何内容。

        但是如果 $puttyline 包含任何 sed 会响应的特殊字符,例如 \ 或 $,这可能会变得很难看。您必须先通过再次调用 sed 来逃避它们,或者......在 bash 中做一些更聪明的事情,我对 bash 太蹩脚了,不知道。例如,双转义所有反斜杠:

        sed 's/\\/\\\\/g'
        

        【讨论】:

        • 如果$puttline 包含特殊字符会不会出现编码问题?
        • @FrankSchwieterman 这实际上更多地取决于您的输入编码是否与您的输出匹配,而不是该解决方案的功能。
        【解决方案6】:

        根据@Spencer Rathbun 的响应,也可以这样做:

           function string_replace {
                #DOC: "${string/match/replace}"
                string=$1
                echo "${string/$2/$3}"
            }
        
            template='my__patternReplacing__appserver'
            match='__patternReplacing__'
            replace='live'
        
            template=$(string_replace "$template" "$match" "$replace")
        

        【讨论】:

          【解决方案7】:

          这是一个 bash 脚本,它把它包装起来

          示例:

          $ search_and_replace.sh "test me out" "test me" ez
          ez out
          

          search_and_replace.sh

          #!/bin/bash
          function show_help()
          {
            echo ""
            echo "usage: SUBJECT SEARCH_FOR REPLACE_WITH"
            echo ""
            echo "e.g. "
            echo ""
            echo "test t a                     => aesa"
            echo "'test me out' 'test me' ez   => ez out"
            echo ""
          
            exit
          }
          
          if [ "$1" == "help" ]
          then
            show_help
            exit
          fi
          if [ -z "$3" ]
          then
            show_help
            exit
          fi
          
          SUBJECT=$1
          SEARCH_FOR=$2
          REPLACE_WITH=$3
          
          echo "$SUBJECT" | sed -e "s/$SEARCH_FOR/$REPLACE_WITH/g"
          

          【讨论】:

            【解决方案8】:

            网上有很多帖子,但对我来说效果很好的帖子如下。

            有两种方法可以实现,如果你想用文件中的另一个字符串替换一个字符串(我的旧字符串是特殊字符:),那么使用这个:

            sed -i '/oldtext:/c\newtext: Rahul'  ./printName.txt
            

            其次,如果你想搜索一个字符串,然后用你的变量替换它,那么这样做:

            #here im concatinating two key + value(myvariable).
            firstkey="oldtext: old"
            
            key="newtext: "
            
            value=$(cat ./variableStoredHere.txt)
            
            key+=$value
            

            以下命令的结果将是 oldtext: old

            echo $firstkey 
            

            以下命令的结果将是 newtext: Rahul

            echo $key 
            
            
            sed -i "s/$firstkey/$key/g" ./printName.txt  
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2014-01-25
              • 2014-03-13
              • 2012-05-11
              • 1970-01-01
              • 2012-10-16
              • 2020-08-14
              • 1970-01-01
              相关资源
              最近更新 更多