使用公共列值合并文件

使用公共列值合并文件

我想使用命令将这两个文件:文件 1(100 万行)和文件 2(10,000 行)合并到新的文件 3(应该是 100 万行)awk

文件1:

 471808241 29164840 1 10001 156197396 
 471722917 21067410 1 31001 135961856 
 471941441 20774160 1 7001  180995072 
 471568655 29042630 1 15001 157502996 
 471524711 20716360 1 4001  180226817 
 471873918 29583520 1 2001  128567298 
 471568650 29042631 1 15002 157502910 

文件 2

610146 156197396 
531101 135961856 
704011 180226817 
502216 128567298 
707012 180995072 
615246 157502996 
685221 157502910 

期望输出:

471808241 29164840 1 10001 156197396 610146 
471722917 21067410 1 31001 135961856 531101 
471941441 20774160 1 7001  180995072 707012 
471568655 29042630 1 15001 157502996 615246 
471524711 20716360 1 4001  180226817 704011 
471873918 29583520 1 2001  128567298 502216 
471568650 29042631 1 15002 157502910 685221

答案1

如果您不介意对文件进行排序,您可以使用join(虽然这对您的情况来说可能不实用,但看看如何完成会很有趣)

首先File 2按公共数字字段排序

sort -k2 "File 2" > file2clean

然后你join可以

sort -k5 "File 1" | join -a 1 -o 1.1 1.2 1.3 1.4 0 2.1 -1 5 -2 2 - file2clean | tee "File 3"

笔记

  • -a 1File 1打印无法配对的行(因为这个文件有更多行,我假设这就是你想要的)
  • -o 1.1 1.2 1.3 1.4 0 2.1输出行的字段顺序 - 我们连接的字段是0,并且1.1是第一个文件的第一个字段,依此类推
  • -1 5 -2 2连接第一个文件的第 5 个字段和第二个文件的第二个字段
  • - file2clean这里-表示沿管道传递的标准输入,即排序后的File 1

完成后,您可以删除中间部分file2clean

答案2

我不知道对于你提到的大小的文件来说它会有多高效,但是既然你要求awk解决方案,那实际上只需要从第二个文件创建一个查找表,然后使用第一个文件的最后一个字段来输入它,例如

awk 'NR==FNR {a[$2]=$1; next} {$(NF+1) = a[$NF]} 1' file2 file1 > file3

请注意,您没有指定在没有匹配的情况下要做什么 - 在这种情况下,它将添加一个空字段。如果这不是所需的行为,您可以先测试是否$NF存在a

相关内容