С GNU awk для массивов массивов:
$ cat tst.awk
NR==FNR { a[$2,$3][$4]; next }
($2,$3) in a {
for (val in a[$2,$3]) {
print val, $4
}
}
$ awk -f tst.awk small_file large_file
a w
b m
c m
и с любым awk (немного менее эффективно):
$ cat tst.awk
NR==FNR { a[$2,$3] = a[$2,$3] FS $4; next }
($2,$3) in a {
split(a[$2,$3],vals)
for (i in vals) {
print vals[i], $4
}
}
$ awk -f tst.awk small_file large_file
a w
b m
c m
Выше при чтении small_file
(NR==FNR
верно только для первого чтения файла - ищите эти переменные на справочной странице awk или в google) создает ассоциативный массив a[]
, который отображает индекс, созданный из конкатенации 2-го и 3-го полей, в список значений 4-е поле для этих 2-х / 3-х комбинаций полей. Затем при чтении large_file
он ищет этот массив для текущей комбинации 2-го и 3-го полей и просматривает все значения, сохраненные для этой комбинации в предыдущей фазе, печатая это значение ($ 4 из small_file) плюс текущие $ 4.
Вы сказали, что ваш маленький файл имеет размер 5,5 МБ, а большой - 25 ГБ. Поскольку 1 МБ составляет около 1 047 600 символов (см. https://www.computerhope.com/issues/chspace.htm), а каждая из ваших строк имеет длину около 8 символов, это означает, что ваш маленький файл имеет длину около 130 тысяч строк, а ваш большой - около 134 миллионов строк, поэтому Я ожидаю, что на компьютере со средним питанием запуск вышеупомянутого должен занять не больше минуты или двух, это, конечно, не займет и часа!