Bash 使用awk如何合并2个文件,例如A&;B和执行左外连接函数,并在两个文件中包含所有列

Bash 使用awk如何合并2个文件,例如A&;B和执行左外连接函数,并在两个文件中包含所有列,bash,awk,Bash,Awk,我有多个不同列数的文件,我需要在第一个文件和第二个文件上进行合并,在awk中分别对第一个文件进行左外连接,并打印两个文件中与两个文件的第一列匹配的所有列 我尝试了以下代码以接近我的输出。但是我无法打印“,”,因为在第二个文件中找不到匹配的数字。下面是代码。Join需要排序,并且比awk花费更多的时间。我的文件很大,比如3000万条记录 awk -F ',' '{ if (NR==FNR){ r[$1]=$0} else{ if($1 in r) r[$1]=r[$1

我有多个不同列数的文件,我需要在第一个文件和第二个文件上进行合并,在awk中分别对第一个文件进行左外连接,并打印两个文件中与两个文件的第一列匹配的所有列

我尝试了以下代码以接近我的输出。但是我无法打印“,”,因为在第二个文件中找不到匹配的数字。下面是代码。Join需要排序,并且比awk花费更多的时间。我的文件很大,比如3000万条记录

awk -F ',' '{  
    if (NR==FNR){ r[$1]=$0}
    else{ if($1 in r) 
    r[$1]=r[$1]gensub($1,"",1)}
}END{for(i in r){print r[i]}}' file1 file2
文件1

文件2

输出

文件1

文件2

期望输出

你可以试试

awk 'BEGIN{FS=OFS=","}
   FNR==NR{d[$1]=substr($0,index($0,",")+1); next}
   {print $0, ($1 in d?d[$1]:",")}' file2 file1
你得到

1,a,b,c,x,y
2,a,b,c,x,y
3,a,b,c,,
5,a,b,c,x,y
1,a,b,c,x,y
2,a,b,c,x,y
3,a,b,c,,
5,a,b,c,x,y

加入
救援:

$ join -t $',' -a 1 -e '' -o 0,1.2,1.3,1.4,2.2,2.3 file1.txt file2.txt
说明:

-t$,'
:字段分隔符标记

-a 1
:如果文件2中没有记录,则不要丢弃文件1中的记录

-e'
:丢失的记录将被视为空字段

-o
:输出格式

file1.txt

1,a,b,c
2,a,b,c
3,a,b,c
5,a,b,c
1,x,y
2,x,y
5,x,y
6,x,y
7,x,y
file2.txt

1,a,b,c
2,a,b,c
3,a,b,c
5,a,b,c
1,x,y
2,x,y
5,x,y
6,x,y
7,x,y
输出

1,a,b,c
2,a,b,c
3,a,b,c
5,a,b,c
1,x,y
2,x,y
5,x,y
6,x,y
7,x,y
上面对gensub()使用GNU awk,对于其他awk,在初始赋值之后,对适当的变量执行[g]sub()只需再执行一步

您可能想要测试性能差异的一个有趣的(至少对我来说!)备选方案是:

$ cat tst.awk
BEGIN { FS=OFS="," }
NR==FNR {
    tail = gensub(/[^,]*,/,"",1)
    idx[$1] = NR
    file2[NR] = tail
    if ( FNR == 1 ) {
        file2[""] = gensub(/[^,]/,"","g",tail)
    }
    next
}
{ print $0, file2[idx[$1]] }

$ awk -f tst.awk file2 file1
1,a,b,c,x,y
2,a,b,c,x,y
3,a,b,c,,
5,a,b,c,x,y

但是我真的不希望它更快,甚至可能更慢。

请告诉我们您尝试过的代码和您发现的问题。您有多少行?我可以提供一个简单的脚本来解析,但对于大文件来说速度会非常慢可能会重复Hi谢谢,但我需要使用awk,因为这需要排序并需要更多时间大家好,我的问题是我在不同的文件中有不同的列号,例如:下面的案例不适用于您的代码。如果您能解释一下您所做的事情,将非常有帮助[cmsuser@cms-app02搅动器[U awk]$类别t4 1,ee,rr 2,rr,rr 3,tt,rr 5,mm,mm[cmsuser@cms-app02搅动器(awk)$类别t1 1 2 3 4 5 6 7 8 9 10[cmsuser@cms-app02搅动器[U awk]$awk'BEGIN{FS=OFS=“,”}FNR==NR{d[$1]=substr($0,index($0,”)+1);next}{print$0,($1在d?d[$1]:“NULL”)}'t4 t1 1,ee,rr 2,rr,rr 3,tt,rr 4,NULL 5,mm,mm 6,NULL 7,NULL 8,NULL 9,NULL 10,NULL所需输出,1,ee,rr 2,rr,rr 3,tt,rr 4,NULL,NULL 5,mm 6,NULL 7,NULL 8,NULL 9,NULL 10,NULL基本上我需要最终输出具有相同数量的列1文件,以空格字符作为分隔符“1 2 3 4 6 7 9 10“,您的输入示例看起来不一样。对不起,它实际上是逐行显示的,当我将其粘贴到此处时,不知何故它没有显示出来。我找到了一个解决方案,但每次都是手工操作。这是基于输出文件的列添加逗号的数量,例如:如果我的输出文件是5列,那么我给出如下awk'BEGIN{FS=OFS=“,”}FNR==NR{d[$1]=substr($0,index($0,”)+1);next}{print$0,($1在d[$1]:“,,,,”)}文件2 file1comma不需要引号或转义
-t,
也可以工作。Hi Ed,如果你能很好地解释一下代码,这将是很有帮助的。谢谢
1,a,b,c,x,y
2,a,b,c,x,y
3,a,b,c,,
5,a,b,c,x,y
$ cat tst.awk
BEGIN { FS=OFS="," }
NR==FNR {
    tail = gensub(/[^,]*,/,"",1)
    if ( FNR == 1 ) {
        empty = gensub(/[^,]/,"","g",tail)
    }
    file2[$1] = tail
    next
}
{ print $0, ($1 in file2 ? file2[$1] : empty) }

$ awk -f tst.awk file2 file1
1,a,b,c,x,y
2,a,b,c,x,y
3,a,b,c,,
5,a,b,c,x,y
$ cat tst.awk
BEGIN { FS=OFS="," }
NR==FNR {
    tail = gensub(/[^,]*,/,"",1)
    idx[$1] = NR
    file2[NR] = tail
    if ( FNR == 1 ) {
        file2[""] = gensub(/[^,]/,"","g",tail)
    }
    next
}
{ print $0, file2[idx[$1]] }

$ awk -f tst.awk file2 file1
1,a,b,c,x,y
2,a,b,c,x,y
3,a,b,c,,
5,a,b,c,x,y