【问题标题】:Bash extract after substring and before substring子字符串之后和子字符串之前的 Bash 提取
【发布时间】:2015-06-06 09:23:36
【问题描述】:

假设我有一个字符串:

random text before authentication_token = 'pYWastSemJrMqwJycZPZ', gravatar_hash = 'd74a97f

我想要一个 shell 命令来提取 "authentication_token = '" 之后和下一个 ' 之前的所有内容。

所以基本上,我想返回pYWastSemJrMqwJycZPZ

我该怎么做?

【问题讨论】:

    标签: string bash sed grep expression


    【解决方案1】:

    使用参数扩展:

    #!/bin/bash
    text="random text before authentication_token = 'pYWastSemJrMqwJycZPZ', gravatar_hash = 'd74a97f"
    token=${text##* authentication_token = \'}   # Remove the left part.
    token=${token%%\'*}                          # Remove the right part.
    echo "$token"
    

    请注意,即使随机文本包含authentication token = '...',它也能正常工作。

    【讨论】:

    • 这绝对是最快的答案,因为它不调用任何外部程序。感谢您提供此解决方案。
    【解决方案2】:

    如果你的 grep 支持 -P 那么你可以使用这个 PCRE 正则表达式,

    $ echo "random text before authentication_token = 'pYWastSemJrMqwJycZPZ', gravatar_hash = 'd74a97f" | grep -oP "authentication_token = '\K[^']*"
    pYWastSemJrMqwJycZPZ
    
    $ echo "random text before authentication_token = 'pYWastSemJrMqwJycZPZ', gravatar_hash = 'd74a97f" | grep -oP "authentication_token = '\K[^']*(?=')"
    pYWastSemJrMqwJycZPZ
    
    • \K 在最终打印时丢弃以前匹配的字符。

    • [^']* 否定字符类,匹配任何字符但不匹配 ' 零次或多次。

    • (?=') 肯定的前瞻,它断言匹配必须后跟单引号。

    【讨论】:

    • 在你的第二个例子中,你的意思是写 .*?(?=') 吗?否则,该示例不会向第一个添加任何内容。
    • @glenn 不,第一个仅适用于此输入,最后不会检查以下'。所以这也匹配没有任何结尾单引号的字符串。但是第二个的积极前瞻断言匹配必须后跟一个单引号。所以这只匹配有单引号和单引号的字符串。
    【解决方案3】:

    IMO,grep -oP 是最好的解决方案。为了完整起见,有几个替代方案:

    sed 's/.*authentication_token = '\''//; s/'\''.*//' <<<"$string"
    
    awk -F "'" '{for (i=1; i<NF; i+=2) if ($1 ~ /authentication_token = $/) {print $(i+1); break}}' <<< "$string"
    

    【讨论】:

      【解决方案4】:

      使用bash 的正则表达式匹配工具。

      $ regex="_token = '([^']+)'"
      $ string="random text before authentication_token = 'pYWastSemJrMqwJycZPZ', gravatar_hash = 'd74a97f'"
      $ [[ $string =~ $regex ]] && hash=${BASH_REMATCH[1]}
      $ echo "$hash"
      pYWastSemJrMqwJycZPZ
      

      使用变量代替文字正则表达式可以简化对空格和单引号的引用。

      【讨论】:

        【解决方案5】:

        我的简单版是

        sed -r "s/(.*authentication_token = ')([^']*)(.*)/\2/"
        

        【讨论】:

          猜你喜欢
          • 2021-01-28
          • 2014-11-24
          • 1970-01-01
          • 2022-11-10
          • 2021-09-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-17
          相关资源
          最近更新 更多