代码之家  ›  专栏  ›  技术社区  ›  Tom

BASH-从字符串中提取数据

  •  0
  • Tom  · 技术社区  · 7 年前

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

    在日志中只有一行包含unquie unit

    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 开,或=但由于值不是按设定的顺序排列的,所以我无法找到最佳的方法。

    我想得到:

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

    谢谢

    3 回复  |  直到 7 年前
        1
  •  2
  •   RavinderSingh13 Nikita Bakshi    7 年前

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

    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
  •  1
  •   tripleee    7 年前

    您最好使用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
    

    gsub

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

        3
  •  1
  •   paxdiablo    7 年前

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

    然后可以简单地使用 bash :

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

    每行上的第一个命令都会剥离行的第一部分,直到并包括 <field-number>=" . 然后,第二个命令去掉第一个引号以外的所有内容(包括第一个引号)。第三,当然,只是呼应了价值观。

    Qual
    reset