【问题标题】:Parsing shebang with sed failure用 sed 失败解析 shebang
【发布时间】:2015-03-11 15:26:17
【问题描述】:

我有一个类似#!/bin/bash --args blah blah 的字符串,我想从中提取“bash”。

str="#\!/bin/bash --args blah blah"
echo "$str" | sed -r s/#\!.*?/(.*?)\>/\1/g

它给了我一个错误“bash: syntax error near unexpected token `('”。

我用-r 启用了扩展正则表达式,不是吗?怎么回事?

【问题讨论】:

    标签: regex linux bash sed


    【解决方案1】:

    你应该引用你的 sed 命令:

    echo "$str" | sed -r "s/#\!.*?/(.*?)\>/\1/g"
    

    在 bash 中,如果括号不在字符串文字内,则它们具有特殊含义。
    此外,您的 sed 命令将为 sed: -e expression #1, char 18: unknown option to 's' 引发错误,因为您的模式中有一个未转义的 /

    【讨论】:

    • 可能是真的,但现在它给了我错误“sed: -e expression #1, char 18: unknown option to `s'”
    • @MightyPork - 正确。这是因为您的搜索模式包含未转义的/。您可以对其进行转义或使用其他分隔符。
    【解决方案2】:

    似乎您的字符串分配是错误的,并且还使用了不同的 sed 分隔符,因为输入包含正斜杠。

    $ str='#!/bin/bash --args blah blah'
    $ sed -r 's~#![^ ]*/([^ ]*)\b.*~\1~g' <<< $str
    bash
    

    【讨论】:

      【解决方案3】:

      使用纯 BASH 内置函数:

      str='#!/bin/bash --args blah blah'
      [[ "$str" =~ \#\!/[^/]+/([^/ ]+) ]] && echo "${BASH_REMATCH[1]}"
      bash
      

      【讨论】:

        【解决方案4】:

        纯 POSIX,没有 bashism,适用于 任何 Bourne Shell:

        $ str='#!/bin/bash --args blah blah'
        $ shebang=${str%% *}      # Remove space and all that follows
        $ shell=${shebang##*/}    # Remove up to and including /
        $ echo $shell
        bash
        

        阅读您的 shell 手册中的“参数扩展”部分,了解有关这些内置字符串处理功能的更多信息。请注意,与使用 shell 内置功能相比,分叉像 sed 这样的外部程序在 CPU 周期方面非常昂贵

        【讨论】:

          【解决方案5】:

          您也可以使用 PCRE:

          echo '#!/bin/bash --args blah blah' | grep -Po "(?<=/)[a-z]+(?= )"
          

          这里的正向向后看(?&lt;=/) 确保/ 在正则表达式之前,正向向前看(?= ) 确保在正则表达式之后有一个空格。所以,只有bash 被选为输出。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-09-22
            • 2019-07-22
            • 2014-04-05
            • 2011-03-28
            • 2019-09-27
            • 2012-10-23
            • 1970-01-01
            相关资源
            最近更新 更多