【问题标题】:Match two files and print the matched strings based on the second file using awk匹配两个文件并使用 awk 根据第二个文件打印匹配的字符串
【发布时间】:2019-05-04 01:31:56
【问题描述】:

我在下面有两个名为 InputFile 和 Ref 的文件

输入文件

1234~code1=yyy:code2=fff:code3=vvv
1256~code2=ttt:code1=yyy:code4=zzz
4567~code4=uuu
8907~code8=ooo:code7=rrr

参考

code2
code3
code8
code7

我必须将 Ref 中的所有记录匹配到 InputFile 的第二列(~ 分隔并将用冒号 (:) 分隔)。如果在 InputFile 中找到 Ref 中的记录,则应在 = 符号后打印前面的值,否则打印无。

期望的输出

1234~fff~vvv~~
1256~ttt~~~
4567~~~~
8907~~~ooo~rrr

我即将将其加载到以 Ref 记录为列的表中。

这是我的脚本:

awk '
BEGIN{
  FS=OFS="~"
}
FNR==NR{
  a[$0]
  next
}
FNR==1 && FNR!=NR{
  print
  next
}
{
  num=split($2,array,"[=:]")
  for(i=1;i<=num;i+=2){
    if(array[i] in a){
      val=val?val OFS array[i+1]:array[i+1]
    }
    else{
      val=val?val OFS "~":"~"
    }
  }
  print $1,val
  val=""
}
' Ref InputFile

它在 InputFile 中打印 Ref 中存在的数组(code1、code2 等),但它不按 Ref 的顺序打印。

脚本的输出

1234~~fff~vvv
1256~ttt
4567~
8907~ooo~rrr

【问题讨论】:

  • output 是您的实际输出还是您想要的输出的另一个版本?您在帖子前面所需的输出和最后一个“输出”中的行顺序看起来与我相同,只是缺少一些字段 - 这是一个问题还是顺序是唯一的问题? in Ref's order 是什么意思? Ref 文件中的行顺序或 Ref 文件内容的字母或数字顺序或其他?
  • 最后一个输出是脚本的实际输出,这是不可接受的,因为我将把输出上传到已经定义了列的表中。表中的列在 Ref 文件中列出,因此输出必须在 ref 文件中对齐。例如,如果在输入文件中找到 code2(在 ref 文件中),则打印该值,否则为空白;下一个;如果在输入文件中找到 code3,则打印该值,否则 blak;next...等等。

标签: shell awk


【解决方案1】:

类似的东西

$ awk -F~ 'NR==FNR {c[NR]=$1; cs=NR; next} 
                   {n=split($2,f,"[=:]"); 
                    delete k; 
                    for(i=1;i<n;i+=2) k[f[i]]=f[i+1]; 
                    printf "%s", $1; 
                    for(i=1;i<=cs;i++) printf "%s", FS k[c[i]]; 
                    print ""}' ref input
1234~fff~vvv~~
1256~ttt~~~
4567~~~~
8907~~~ooo~rrr

由于您想将订单保留在 ref 文件中,因此不要将它们作为键插入到数组中,而是将它们作为以订单号(此处为行号)为索引的值添加。否则你会失去秩序,我认为这是你脚本的(唯一?)问题。

【讨论】:

    【解决方案2】:
    $ cat tst.awk
    BEGIN {
        FS  = "[~:=]"
        OFS = "~"
    }
    NR == FNR {
        refs[++numRefs] = $0
        next
    }
    {
        delete ref2val
        for (fldNr=2; fldNr<NF; fldNr+=2) {
            ref2val[$fldNr] = $(fldNr+1)
        }
    
        printf "%s%s", $1, OFS
        for (refNr=1; refNr<=numRefs; refNr++) {
            ref = refs[refNr]
            printf "%s%s", ref2val[ref], (refNr<numRefs ? OFS : ORS)
        }
    }
    
    $ awk -f tst.awk refs file
    1234~fff~vvv~~
    1256~ttt~~~
    4567~~~~
    8907~~~ooo~rrr
    

    【讨论】:

      猜你喜欢
      • 2016-07-30
      • 1970-01-01
      • 1970-01-01
      • 2015-03-27
      • 1970-01-01
      • 2018-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多