如何用awk合并两个文件?

mah*_*ood 4 awk

我有两个文件,它们的顺序相同,行数相同:

file1(只有2列):

562_201 RIR1
562_202 RIR1
562_203 RIR1
562_204 RIR1
562_205 RIR1
562_206 RIR1
562_207 RIR1
562_208 RIR1
562_209 RIR1
562_210 WR1 
562_211 WR1 
562_212 WR1 
Run Code Online (Sandbox Code Playgroud)

file2(我应该说file2有超过百万行!):

562_201 0101
562_202 0101
562_203 0101
562_204 0101
562_205 0101
562_206 0101
562_207 0101
562_208 0101
562_209 0101
562_210 0101
562_211 0101
562_212 0101
Run Code Online (Sandbox Code Playgroud)

我想合并他们得到:

562_201 RIR1 0101
562_202 RIR1 0101
562_203 RIR1 0101
562_204 RIR1 0101
562_205 RIR1 0101
562_206 RIR1 0101
562_207 RIR1 0101
562_208 RIR1 0101
562_209 RIR1 0101
562_210 WR1  0101
562_211 WR1  0101
562_212 WR1  0101
Run Code Online (Sandbox Code Playgroud)

谢谢!

kev*_*kev 10

您可以使用join命令:

$ join file1.txt file2.txt
Run Code Online (Sandbox Code Playgroud)


gho*_*oti 6

我不确定,但join命令可能会将两个文件加载到内存中.如果一个或两个文件很大,那可能会有问题.

这应该通过仅将较小的文件加载到内存中的数组中,然后通过管道连接数据来避免此问题.

#!/usr/bin/awk -f

# Load file1 into an array...
BEGIN {
  while (getline < "file1") {
    file1[$1]=$0;
  }
}

{
  key=$1;    # Store the key
  $1="";     # Blank the key (now $0 starts with the field separator)
  print file1[key] $0;
}
Run Code Online (Sandbox Code Playgroud)

用法:

[ghoti@pc ~/tmp]$ ./join.awk file2
562_201 RIR1 0101
562_202 RIR1 0101
562_203 RIR1 0101
562_204 RIR1 0101
562_205 RIR1 0101
562_206 RIR1 0101
562_207 RIR1 0101
562_208 RIR1 0101
562_209 RIR1 0101
562_210 WR1 0101
562_211 WR1 0101
562_212 WR1 0101
Run Code Online (Sandbox Code Playgroud)

正如格伦建议的那样,符号:

awk 'NR==FNR {file1[$1]=$0; next} {$1=file1[$1]; print}' file1 file2
Run Code Online (Sandbox Code Playgroud)

对于将第一个文件加载到数组中的相同想法,这是一种更经典的方法.

如果具有数百万行的这些文件太大而无法存储在内存中,您还可以在自己的管道中逐步执行每个文件,从每个文件一次只加载一行到内存中:

$ awk '{getline line < "file1"; print line,$2}' file2
Run Code Online (Sandbox Code Playgroud)

这将读取file2中的行,并且每行还会从file1读取一行到变量中,然后从file2打印变量和额外字段.一次只有一行存储在内存中.

原样,它假设第一个字段总是在每个文件中匹配 - 也就是说,没有错误检查.如果你想要一些,它很容易实现:

$ awk '{getline line < "file1"; split(line,a); if(a[1]!=$1) {exit(1)} print line,$2}' file2
Run Code Online (Sandbox Code Playgroud)

如果$1不匹配,退出状态将退出1 .


Ken*_*ent 5

AWK

awk 'NR==FNR{a[$1]=$2;next;}gsub($1,$1" "a[$1])' file1 file2
Run Code Online (Sandbox Code Playgroud)