【问题标题】:Using sed captured group variable as input for bash command使用 sed 捕获的组变量作为 bash 命令的输入
【发布时间】:2018-02-11 09:45:00
【问题描述】:

我有这样的文字: TEXT="I need to replace the hostname [[google.com]] with it's ip in side the text"

有没有办法使用类似下面的东西,但工作? sed -Ee "s/\[\[(.*)\]\]/`host -t A \1 | rev | cut -d " " -f1 | rev`/g" <<< $TEXT

看起来 \1 的值没有传递给 sed 中使用的 shell 命令。

谢谢

【问题讨论】:

    标签: regex linux string bash sed


    【解决方案1】:

    谢谢大家,

    我做了以下解决方案:

    function host_to_ip () {
        echo $(host -t A $1 | head -n 1 | rev | cut -d" " -f1  | rev)
    }
    
    function resolve_hosts () {
        local host_placeholders=$(grep -o -e "##.*##" $1)
    
        for HOST in ${host_placeholders[@]}
        do
            sed -i -e "s/$HOST/$(host_to_ip $(sed -Ee 's/##(.*)##/\1/g' <<< $HOST))/g" $1 
        done
     }
    

    resolve_hosts 获取文本文件作为参数的地方

    【讨论】:

      【解决方案2】:

      这行得通:

      #!/bin/bash
      
      txt="I need to replace the hostname [[google.com]] with it's ip in side the text"
      host_name=$(sed -E 's/^[^[]*\[\[//; s/^(.*)\]\].*$/\1/' <<<"$txt")
      ip_addr=$(host -tA "$host_name" | sed -E 's/.* ([0-9.]*)$/\1/')
      echo "$txt" | sed -E 's/\[\[.*\]\]/'"$ip_addr/"
      
      # I need to replace the hostname 172.217.4.174 with it's ip in side the text
      

      【讨论】:

        【解决方案3】:

        它必须是一个由两部分组成的命令,一个用于获取 bash 可以使用的变量,另一个用于直接用 sed 替换 /s/。

        TEXT="I need to replace the hostname [[google.com]] with it's ip in side the text"
        DOMAIN=$(echo $TEXT | sed -e 's/^.*\[\[//' -e 's/\]\].*$//')
        echo $TEXT | sed -e 's/\[\[.*\]\]/'$(host -tA $DOMAIN | rev | cut -d " " -f1 | rev)'/'
        

        但是,使用how to split a string in shell and get the last field 更干净

        TEXT="I need to replace the hostname [[google.com]] with it's ip in side the text"
        DOMAIN=$(echo $TEXT | sed -e 's/^.*\[\[//' -e 's/\]\].*$//')
        HOSTLOOKUP=$(host -tA $DOMAIN)
        echo $TEXT | sed -e 's/\[\[.*\]\]/'${HOSTLOOKUP##* }/
        

        简短的版本是您不能按照您期望的方式混合 sed 和 bash。

        【讨论】:

          【解决方案4】:

          反引号插值由 shell 执行, 而不是 sed。这意味着您的反引号将在 sed 命令运行之前被命令的输出替换,或者(如果您正确引用它们)它们根本不会被替换,sed 将看到反引号。

          您似乎试图让 sed 执行替换,然后让 shell 执行反引号插值。

          您可以通过正确引用它们来使反引号越过外壳:

          $ echo "" | sed -e 's/^/`hostname`/'
          `hostname`
          

          但是,在这种情况下,您将不得不在 shell 命令行中使用生成的字符串来再次引起反引号插值。

          根据您对 awk、perl 或 python 的感觉,我建议您使用其中一个来一次性完成这项工作。或者,您可以先将主机名提取到不带反引号的命令中,然后执行命令以获取所需的 IP 地址,然后在另一遍中替换它们。

          【讨论】:

            猜你喜欢
            • 2017-01-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-02-07
            • 2020-03-22
            • 1970-01-01
            • 2011-07-27
            相关资源
            最近更新 更多