我有两个文件,它们的顺序相同,行数相同:
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)
谢谢!
我不确定,但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 .
AWK
awk 'NR==FNR{a[$1]=$2;next;}gsub($1,$1" "a[$1])' file1 file2
Run Code Online (Sandbox Code Playgroud)