【问题标题】:BASH - Extract Data from StringBASH - 从字符串中提取数据
【发布时间】:2019-02-21 02:09:03
【问题描述】:

我有一个返回数千行数据的日志,我想从中提取一些值。

在日志中只有一行包含 unquie unit 引用,因此我可以使用 grep 进行查找:

grep "unit=Central-C152" logfile.txt

这会产生类似于以下内容的一行输出:

a3cd23e,85d58f5,53f534abef7e7,unit=Central-C152,locale=32325687-8595-9856-1236-12546975,11="School",1="Mr Green",2="Qual",3="SWE",8="report",5="channel",7="reset",6="velum"

行的格式可能会改变,因为值的顺序不会总是在相同的位置。

我正在尝试研究如何将 2 和 7 的值放入单独的变量中。 我曾考虑过cut on 或 =,但由于这些值不是按固定顺序排列的,我无法找到最好的方法。

我想得到:

var state=value of 2 without quotes var mode=value of 7 without quotes

任何人都可以建议最好的方法吗?

谢谢

【问题讨论】:

    标签: string bash variables


    【解决方案1】:

    请您尝试以下创建变量的值。

    state=$(awk '/unit=Central-C152/ && match($0,/2=\"[^"]*/){print substr($0,RSTART+3,RLENGTH-3)}' Input_file)
    mode=$(awk '/unit=Central-C152/ && match($0,/7=\"[^"]*/){print substr($0,RSTART+3,RLENGTH-3)}'  Input_file)
    

    您也可以通过以下操作打印它们。

    echo "$state"
    echo "$mode"
    

    说明:现在也添加命令说明。

    awk '                                           ##Starting awk program here.
    /unit=Central-C152/ && match($0,/2=\"[^"]*/){   ##Checking condition if a line has string (unit=Central-C152) and using match using REGEX to check from 2 to till "
      print substr($0,RSTART+3,RLENGTH-3)           ##Printing substring starting from RSTART+3 till RLENGTH-3 characters.
    }
    ' Input_file                                    ##Mentioning Input_file name here.
    

    【讨论】:

      【解决方案2】:

      在 awk 中完成所有处理可能会更好。

      awk -F, '/unit=Central-C152/ {
          for(i=1;i<=NF;++i)
              if($i ~ /^[27]="/) {
                  b[++k] = $i
                  sub(/^[27]="/, "", b[k])
                  sub(/"$/, "", b[k])
                  gsub(/\\/, "", b[k])
              }
          print "state " b[1] ", mode " b[2]
          }' logfile.txt
      

      这假定字段总是以相同的顺序出现(2 在 7 之前)。也许您需要更改或禁用 gsub 以删除值中的反斜杠。

      如果您想做的不仅仅是打印值,那么将您拥有的任何 Bash 代码重构到 Awk 中通常是比在 Bash 中进行此处理更好的方法。

      【讨论】:

        【解决方案3】:

        假设您已经在变量中包含该行,例如:

        line="$(grep 'unit=Central-C152' logfile.txt | head -1)"
        

        然后您可以简单地使用bash 的内置参数替换功能:

        f2=${line#*2=\"} ; f2=${f2%%\"*} ; echo ${f2}
        f7=${line#*7=\"} ; f7=${f7%%\"*} ; echo ${f7}
        

        每行的第一个命令会删除该行的第一部分,直到 &lt;field-number&gt;=" 并包括在内。然后,第二个命令会删除(包括)第一个引号之外的所有内容。当然,第三个只是简单地呼应了这个值。

        当我对您的输入行运行这些命令时,我看到:

        Qual
        reset
        

        据我所知,这就是你所追求的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-03
          • 1970-01-01
          • 1970-01-01
          • 2023-03-17
          • 2012-09-24
          • 2022-10-19
          • 2019-05-21
          相关资源
          最近更新 更多