按关键字提取

时间:2015-04-29 09:02:19

标签: shell awk

输入文件:

11 message1(num:1;name:"ee";job:aaffdfd);
12 message2(category:"dds";num:2;name:"Dfdsf");

输出:

11,1,ee,aaffdfd,"message1(num:1;name:"ee";job:aaffdfd)"
12,2,Dfdsf,0,"message2(category:"dds";num:2;name:"Dfds

这就是我试过的

awk '{print $1}' all.txt > out1
awk '{ printf("\""); for (i = 2; i <= NF; i++) { printf("%s ", $i); } printf("\"\n") }' all.txt  > out2
awk -F'name:"|";' '{print $2}' all.txt > out3
awk -F".*job:|;|)" '/classtype:/{print $2;next}{print 0}' all.txt > out4
awk -F".*num:|;|)" '{print $2}' all.txt > out5

paste   out1 out2 out3 out4 out5 > final 

输出文件的列应该是以下方式:

  1. 第一列 - 与输入文件的第一列相同
  2. 第二列 - num:和;之间的数字;
  3. 第三列 - 名称之间的字符串:&#34;和&#34 ;;
  4. 作业之间的第四列 - 字符串:和;如果它不在输入文件行中,请在输出中将其设为0
  5. 第五栏 - 从第二栏到第一栏的所有内容
  6. 目前,我使用不同的awk命令将所有字段分别提取到不同的文件中,然后使用paste命令合并所有文件。 是否可以使用单个awk命令或更优化的方式?

2 个答案:

答案 0 :(得分:3)

它并不漂亮,但是使用GNU awk可以实现所需的输出:

$ awk -v OFS=, '{sub(/;$/,""); print $1,
    gensub(/.*num:([0-9]+).*/,"\\1",1),
    gensub(/.*name:"([^"]+).*/,"\\1",1),
    (/job/?gensub(/.*job:([^;)]+).*/,"\\1",1):0),
    "\""$2"\""}' file
11,1,ee,aaffdfd,"message1(num:1;name:"ee";job:aaffdfd)"
12,2,Dfdsf,0,"message2(category:"dds";num:2;name:"Dfdsf")"

输出字段分隔符OFS设置为逗号。 sub从每行末尾删除分号。这里使用gensub来提取您感兴趣的行的部分。它返回每个替换的结果。如果行上没有匹配0,则使用三元运算符添加/job:/。使用默认字段分隔符,$2包含第一个数字后的所有内容。

答案 1 :(得分:0)

只是使用split和gsub来实现你的结果

awk ' 
{
 sec_hash["job"]=0;
 second=$2;
 gsub(/message[0-9]*\(|\);|"/,"",second);
 split(second, sec_array, ";"); 
 for(var in sec_array) 
 {
  split(sec_array[var],key_val_array, ":");
  sec_hash[key_val_array[1]]=key_val_array[2];
 }    
 print $1 "," sec_hash["num"] "," sec_hash["name"] "," sec_hash["job"] ",\"" $2 "\"" 
}' input