【问题标题】:Extracting by keywords按关键字提取
【发布时间】:2015-04-29 09:02:19
【问题描述】:

输入文件:

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. 第三列 - 名称之间的字符串:" 和 ";
  4. job: 和 ; 之间的第四列字符串如果输入文件中不存在,则在输出中设为0
  5. 第五列 - 从第二列到行尾的所有内容

目前我使用不同的 awk 命令将所有字段分别提取到不同的文件中,然后使用 paste 命令合并所有文件。 是否可以使用单个 awk 命令或更优化的方式?

【问题讨论】:

  • 你能展示一下你到目前为止的尝试吗?我相信这将有助于理解问题
  • 我认为您不应该发布这个新问题 - 最好编辑 your previous question 以便它包含此处的详细信息,显示示例输入和 cmets 中的解释在接受的答案下方。

标签: shell awk


【解决方案1】:

它并不漂亮,但这是一种使用 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 在这里用于提取您感兴趣的行的部分。它返回每个替换的结果。如果在线上没有匹配到/job:/,则使用三元运算符添加0。使用默认字段分隔符,$2 包含第一个数字之后的所有内容。

【讨论】:

  • 如果输入是:11 abc message1(num:1;name:"ee";job:aaffdfd);输出:11,1,ee,aaffdfd,"abc message1(num:1;name:"ee";job:aaffdfd)"
  • 如果您理解我的回答,您应该可以自己解决。如果有不清楚的地方,请告诉我。
  • 在某些情况下,第四列以 [ 开头并以 ] 结尾。只有在这种情况下,我才需要用 [ 和 ] 替换它。是否可以将其包含在上述解决方案中?我可以单独使用它,但不能使用上述方法。
  • @user3823859 我认为您应该提出一个单独的问题,显示新的输入和您尝试过的内容。如果你想参考这个答案,或者在你的尝试中使用它,那很好。
  • 如果输入如上(从 message1(num:1;name:"ee";job:aaffdfd); 编辑到 message1 (num:1;name:"ee";job:aaffdfd ); ) 并且需要的输出是:message1 (num:1;name:"ee";job:aaffdfd);尝试的命令未以正确格式提供输出。 awk '{print $2, for (i = 3; i
【解决方案2】:

刚刚使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-09
    • 1970-01-01
    • 2017-02-04
    • 1970-01-01
    • 2022-06-22
    • 2022-07-31
    • 1970-01-01
    相关资源
    最近更新 更多