【问题标题】:Bash: Extract variable value from stringBash:从字符串中提取变量值
【发布时间】:2022-01-06 14:25:48
【问题描述】:

我需要从日志文件中提取变量“错误”的值。这是一个示例行:

WARN (Periodic Recovery) IJ000906: error=15 check server.log

我需要捕获“错误”的值。查看类似的答案,我想出了:

echo "WARN (Periodic Recovery) IJ000906: error=15 check server.log" |  grep -P '\d+ (error=?)' -o

但是它不会产生任何价值。您能为这种情况推荐一个可行的解决方案吗?

【问题讨论】:

  • ? 是运算符,而不是通配符。您正在尝试匹配字符串error,后跟可选的=
  • error 之前的空格前面的字符是:,而不是数字时,您尝试匹配error 之前的空格之前的数字。
  • 为什么必须使用 POSIX shell?使用 bash 或 zsh,您将拥有更多可能性。

标签: shell awk sed grep


【解决方案1】:

使用sed

$ echo "WARN (Periodic Recovery) IJ000906: error=15 check server.log" | sed 's/.*error=\([^ ]*\).*/\1/'
15

【讨论】:

    【解决方案2】:

    对于 perl 兼容的正则表达式,您正在寻找“lookbehind”断言。

    要查找以字符串“error=”开头的数字,您需要:

    echo "$line" | grep -o -P '(?<=error=)\d+'    # => 15
    

    the pcresyntax(3) man page

    【讨论】:

      【解决方案3】:

      你可以使用这个grep:

      s='WARN (Periodic Recovery) IJ000906: error=15 check server.log'
      grep -oP '\berror=\K\d+' <<< "$s"
      
      15
      

      正则表达式详细信息:

      • \b: 匹配单词边界
      • error=:匹配error=文字
      • \K: 重置匹配信息
      • \d+:匹配 1+ 位并打印出来

      【讨论】:

      • 我建议用 \b 替换 \d+: -- 我不认为前面的数字冒号空格是要求的一部分。
      • 谢谢@glennjackman!我使用它的原因是因为 OP 使用 \d+ (error=?) 作为正则表达式模式,即尝试在空格 + error 之前匹配 1+数字。
      【解决方案4】:

      我会按照下面的方式使用 GNU AWK,让 file.txt 内容成为

      WARN (Periodic Recovery) IJ000906: error=15 check server.log
      

      然后

      awk 'BEGIN{FPAT="error=[0-9]+"}{print substr($1,7)}' file.txt
      

      输出

      15
      

      解释:我通知 GNU AWK 该列是 error= 后跟 1 个或多个使用字段模式 (FPAT) 的数字,对于每行打印从第 7 个字符开始的第一个字段,使用 substr 字符串函数。 7 as error= 有 6 个字符。注意:此解决方案将打印每行第一次出现的error=value。

      (在 gawk 4.2.1 中测试)

      【讨论】:

        【解决方案5】:

        使用bash >= 3.0。

        v='WARN (Periodic Recovery) IJ000906: error=15 check server.log'
        
        [[ $v =~ error=([0-9]+) ]] && echo "${BASH_REMATCH[1]}"
        

        输出:

        15

        【讨论】:

          【解决方案6】:

          第一种解决方案:使用您显示的示例,请尝试遵循awk 代码。

          awk -F'error=| check' '{print $2}' Input_file
          

          解释: 简单的解释是,将所有行的字段分隔符设置为error= check。然后打印行的第二个字段,将在error= 之后和 check 之前打印值,如图所示。



          第二个解决方案:在这里使用awkmatch函数。

          awk 'match($0,/error=[^[:space:]]+/){print substr($0,RSTART+6,RLENGTH-6)}' Input_file
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-06-03
            • 2015-08-27
            • 2021-05-27
            • 1970-01-01
            • 1970-01-01
            • 2016-02-06
            • 2012-09-09
            • 1970-01-01
            相关资源
            最近更新 更多