awk根据文本中间的值解析数据

时间:2015-04-28 14:55:07

标签: bash awk

我有以下输入:

adm.cd.rrn.vme.abcd.name = foo
adm.cd.rrn.vme.abcd.test = no
adm.cd.rrn.vme.abcd.id = 123456
adm.cd.rrn.vme.abcd.option = no
adm.cd.rrn.vme.asfa.name = bar
adm.cd.rrn.vme.asfa.test = no
adm.cd.rrn.vme.asfa.id = 324523
adm.cd.rrn.vme.asfa.option = yes
adm.cd.rrn.vme.xxxx.name = blah
adm.cd.rrn.vme.xxxx.test = no
adm.cd.rrn.vme.xxxx.id = 666666
adm.cd.rrn.vme.xxxx.option = no

如何提取与特定ID相关的所有值? 例如,如果我有id == 324523,我希望打印nametestoption的值:

bar no yes

是否可以在单个awk命令(或bash中的任何类似命令)中实现?

编辑:根据输入,这是我的解决方案,直到现在:

MYID=$(awk -F. '/'"${ID}"$'/{print $5}' ${TMP_LIST})
awk -F'[ .]' '{
                if ($5 == "'${MYID}'") {
                        if ($6 == "name")    {name=$NF}
                        if ($6 == "test")    {test=$NF}
                        if ($6 == "option")  {option=$NF}
                }
        } END {print name,test,option}' ${TMP_LIST})

由于

3 个答案:

答案 0 :(得分:3)

$ cat tst.awk
{ rec = rec $0 RS }
/option/ {
    if (rec ~ "id = "tgt"\n") {
        printf "%s", rec
    }
    rec = ""
    next
}

$ awk -v tgt=324523 -f tst.awk file
adm.cd.rrn.vme.asfa.name = bar
adm.cd.rrn.vme.asfa.test = no
adm.cd.rrn.vme.asfa.id = 324523
adm.cd.rrn.vme.asfa.option = yes

或者如果您愿意:

$ cat tst.awk
BEGIN { FS="[. ]" }
$(NF-2) == "id" { found = ($NF == tgt ? 1 : 0); next }
{ rec = (rec ? rec OFS : "") $NF }
$(NF-2) == "option" { if (found) print rec; rec = ""; next }

$ awk -v tgt=324523 -f tst.awk file
bar no yes

答案 1 :(得分:2)

首先,我用xargs转换每行记录,然后查找包含正则表达式的行并打印搜索的列

cat input | xargs -n 12 | awk '{if($0~/id\s=\s324523\s/){ print $3, $6, $12}}'

更通用的解决方案:

awk 'BEGIN{FS="\\.|\\s"; } #field separator is point \\. or space \\s
{
  a[$5"."$6]=$8;           #store records in associative array a
  if($8=="324523" && $6=="id"){
    reg[$5]=1;             #if is record found, add to associative array reg
  }
}END{
  for(k2 in reg){
    s=""
    for(k in a){
      if(k~"^"k2"\\."){  #if record is an element of "reg" then add to output "s"
        s=k":"a[k]" "s
      }
    }
    print s;
  }
}' input

答案 2 :(得分:1)

如果你的输入格式是固定的,你可以这样做:

grep -A1 -B2 'id\s*=\s*324523$' file|awk 'NR!=3{printf "%s ",$NF}END{print ""}' 

您也可以将-F'='添加到a​​wk部分。

它可以由awk单独完成,但grep可以节省一些打字......