Мне было интересно, какое из следующих решений было «самым быстрым» для «больших» файлов:
awk 'FNR==NR{a[$0]++}FNR!=NR && !a[$0]{print}' file1 file2 # awk1 by SiegeX
awk 'FNR==NR{a[$0]++;next}!($0 in a)' file1 file2 # awk2 by ghostdog74
comm -13 <(sort file1) <(sort file2)
join -v 2 <(sort file1) <(sort file2)
grep -v -F -x -f file1 file2
Коротко, результаты моих тестов:
- Не использовать
grep -Fxf
, это намного медленнее (в моих тестах 2-4 раза). comm
немного быстрее, чем join
. - Если file1 и file2 уже отсортированы,
comm
и join
намного быстрее, чем awk1 + awk2.(Конечно, они не предполагают сортировку файлов.) - awk1 + awk2, предположительно, используют больше оперативной памяти и меньше ЦП.Реальное время выполнения меньше для
comm
, вероятно, из-за того, что он использует больше потоков.Время процессора меньше для awk1 + awk2.
Для краткости опущу полные детали.Тем не менее, я предполагаю, что любой желающий может связаться со мной или просто повторить тесты.Грубо говоря, установка была
# Debian Squeeze, Bash 4.1.5, LC_ALL=C, slow 4 core CPU
$ wc file1 file2
321599 321599 8098710 file1
321603 321603 8098794 file2
Типичные результаты самых быстрых запусков
awk2: real 0m1.145s user 0m1.088s sys 0m0.056s user+sys 1.144
awk1: real 0m1.369s user 0m1.324s sys 0m0.044s user+sys 1.368
comm: real 0m0.980s user 0m1.608s sys 0m0.184s user+sys 1.792
join: real 0m1.080s user 0m1.756s sys 0m0.140s user+sys 1.896
grep: real 0m4.005s user 0m3.844s sys 0m0.160s user+sys 4.004
Кстати, для любителей: кажется, что a[$0]=1
быстрее, чем a[$0]++
, и (!($0 in a))
быстрее (!a[$0])
.Итак, для решения awk я предлагаю:
awk 'FNR==NR{a[$0]=1;next}!($0 in a)' file1 file2