匹配两个文件,并使用awk根据第二个文件打印匹配的字符串



下面有两个名为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

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

脚本的输出

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

类似于您的

$ 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文件中保留顺序,所以不要将它们作为键插入数组,而是将它们作为用顺序号(此处为行号(索引的值添加。否则你会失去秩序,我认为这是你剧本的(唯一?(问题。

$ 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

最新更新