Я не уверен, но команда 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;
}
Использование:
[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
Как предложил Гленн, нотация:
awk 'NR==FNR {file1[$1]=$0; next} {$1=file1[$1]; print}' file1 file2
- это более классический подход к той же идее загрузки первого файла в массив.
Если эти файлы с миллионами строк слишком велики для хранения в памяти, вы также можете пройти по каждому файлу в отдельном канале, загружая только одну строку за раз из каждого файла в память:
$ awk '{getline line < "file1"; print line,$2}' file2
Это читает строки в файле2, и для каждой строки также читает строку из файла1 в переменную, а затем печатает переменную и дополнительное поле из файла2.В памяти хранится только одна строка за раз.
Как есть, предполагается, что первое поле всегда совпадает в каждом файле, то есть проверка ошибок отсутствует.Если вы хотите что-то, это достаточно просто реализовать:
$ awk '{getline line < "file1"; split(line,a); if(a[1]!=$1) {exit(1)} print line,$2}' file2
Это завершится со статусом выхода 1, если $1
не совпадает.