【问题标题】:Using bash variable names as match replacement in perl regex substitution command line在 perl 正则表达式替换命令行中使用 bash 变量名作为匹配替换
【发布时间】:2020-01-25 14:17:57
【问题描述】:

我正在尝试用它们在 shell 中匹配的 bash 变量的值替换由字符串中的字符分隔的子字符串。

到目前为止,我已经尝试过,但没有成功:

varone="noob"
vartwo="trivial"
echo "my {varone} and {vartwo} question" | perl -pe 's|(.*){(\w+)}(.*)|${1}'$(echo "${'${2}'}")'${3}|g'

但我明白了:

bash: ${'${2}'}: bad substitution

知道如何做到这一点吗?提前致谢!

【问题讨论】:

    标签: regex bash shell perl command-line


    【解决方案1】:

    不要从 shell 生成 Perl 代码! It isn't easy.

    不生成代码,而是将值传递给脚本。 This answer 展示了几种可以将值传递给 Perl 单行器的方法。导出要插值的变量在这里是最简单的。

    export varone="noob"
    export vartwo="trivial"
    echo "my {varone} and {vartwo} question" |
       perl -pe's/\{(\w+)\}/$ENV{$1}/g'
    

    这也意味着您可以插入其他变量,例如PATH。如果这不好,您将不得不以某种方式检查变量名是否合法。

    export varone="noob"
    export vartwo="trivial"
    echo "my {varone} and {vartwo} question" |
       perl -pe's/\{(varone|vartwo)\}/$ENV{$1}/g'
    

    【讨论】:

    • 就是这样,我也很欣赏没有任何外部存储的 perl 解决方案,感谢您指出这一点!
    【解决方案2】:

    您的主要问题是您需要使用export 才能在您的子流程中看到您的变量(如perl 流程)。

    export varone="noob"
    export vartwo="trivial"
    echo "my {varone} and {vartwo} question" | perl -pe '...'
    

    您还需要知道在 Perl 程序中使用 %ENV 哈希访问 shell 变量。

    所以你的代码可以简化为:

    export varone="noob"
    export vartwo="trivial"
    echo "my {varone} and {vartwo} question" | perl -pe 's|\{(\w+)}|$ENV{$1}|g'
    

    您可以考虑添加一个选项来检查未知变量。

    export varone="noob"
    export vartwo="trivial"
    echo "my {varone} and {vartwo} question {varxxx}" | perl -pe 's|\{(\w+)}|$ENV{$1}//"UNKNOWN"|g'
    

    但我建议您查看proper templating engine。

    【讨论】:

      【解决方案3】:

      使用export 访问 Perl 脚本中的 bash 变量:

      试试这个:

      export varone="noob"
      export vartwo="trivial"
      echo "my {varone} and {vartwo} question" | perl -pe 's|(.*){(\w+)}(.*){(\w+)}(.*)|${1}${ENV{$2}}${3}${ENV{$4}}${5}|g'
      

      示例

      echo "my {varone} and {vartwo} question" | perl -pe 's|(.*){(\w+)}(.*){(\w+)}(.*)|${1}${ENV{$2}}${3}${ENV{$4}}${5}|g'
      my noob and trivial question
      

      【讨论】:

        【解决方案4】:

        这是另一种方法:

        echo "my {varone} and {vartwo} question" | \
             perl -wpE 'BEGIN{ %h = @ARGV;@ARGV=() } s|{(\w+)\}|$h{$1}|g' \
             "varone" "$varone" "vartwo" "$vartwo" 
        

        输出:

        my noob and trivial question
        

        【讨论】:

        • -E 不向前兼容。除了一次性脚本之外,不应使用它。
        猜你喜欢
        • 1970-01-01
        • 2016-02-11
        • 1970-01-01
        • 1970-01-01
        • 2023-03-18
        • 2012-08-26
        • 2012-05-16
        • 2015-07-24
        • 1970-01-01
        相关资源
        最近更新 更多