Если ваша цель состоит в том, чтобы найти общие или необычные строки, comm
моя команда будет здесь.
Он сравнивает два файла и показывает - в трех столбцах - строки, которые являются уникальными для файла 1, строки, которые являются уникальными для файла 2, и строки, которые появляются в обоих файлах соответственно. Вы можете передать ему флаги, чтобы подавить любой из этих выходных данных. Например, comm -1 file1 file2
будет подавлен первый столбец, уникальные для file1. comm -12 file1 file2
будет показывать только вещи в обоих файлах.
Есть одна большая оговорка: входные данные должны быть отсортированы. Мы можем обойти это.
Это покажет вам все в abc, чего нет в mno:
comm -23 <(sort abc.txt) <(sort mno.txt)
И вы можете передать это, wc -l
чтобы получить счет.
Причина, по которой я согласен, comm
заключается в том, что после сортировки файлов параллельное сравнение в вычислительном отношении действительно просто. Если вы имеете дело с миллионами из них, это будет иметь значение.
Это можно продемонстрировать с помощью нескольких фиктивных файлов. У меня довольно быстрый компьютер, поэтому, чтобы показать разницу между подходами, мне нужен довольно большой набор образцов. Я пошел на 10 миллионов 10-символьных строк на файл.
$ cat /dev/urandom | tr -dc '0-9' | fold -w 10 | head -10000000 > abc.txt
$ cat /dev/urandom | tr -dc '0-9' | fold -w 10 | head -10000000 > mno.txt
$ time comm -23 <(sort abc.txt) <(sort mno.txt) | wc -l
... 0m10.653s
$ time grep -Fcxv -f abc.txt mno.txt
... 0m23.920s
$ time grep -Fcwv -f abc.txt mno.txt
... 0m40.313s
$ time awk 'NR==FNR{a[$0]++};NR!=FNR && a[$0]' abc.txt mno.txt | wc -l
... 0m12.161s
Сортировка - это то, что занимает большую часть времени у меня. Если мы притворимся, что abc.txt является статическим, мы можем предварительно отсортировать его, что значительно ускоряет будущие сравнения:
$ sort abc.txt abc-sorted.txt
$ time comm -23 abc-sorted.txt <(sort mno.txt) | wc -l
... 0m7.426s
Вы можете посмотреть на это и считать несколько секунд неуместными, но я должен подчеркнуть, что они работают на высокопроизводительном компьютере. Если вы хотите сделать это на (например) Raspberry Pi 3, вы будете смотреть на гораздо более медленные обороты, и разница увеличится до точки, которая на самом деле имеет значение.
grep -cxvFf abc.txt mno.txt
?fgrep
,egrep
чередуется якобы осуждается (в пользуgrep -F
,grep -E
- хотя я не уверен , что кто -то считает , что они когда - нибудь уйти-x
при использовании-F
?abcdef
должно ли это считаться совпадением или несоответствиемabcd
?Мы могли бы использовать awk для выполнения работы, передав два файла: сначала файл шаблона, а затем файл, который мы хотим проверить. Когда мы читаем первый файл, мы знаем это,
NR==FNR
и тогда мы можем читать строки в массив. КогдаNR!=FNR
мы проверяем, установлен ли массив для такой строки.И наоборот, мы можем отменить шаблон для печати тех строк, которые не находятся в
abc.txt
И если мы хотим напечатать количество тех, кого мы можем использовать
sort
иwc
:источник
abc.txt
-mno.txt
которая есть{xyz, pqrs}
.Если какое-либо из списков слов не отсортировано, было бы быстрее использовать эффективную структуру данных набора для запоминания общих слов.
питон
Применение:
Python (более эффективный)
Если вы хотите сэкономить немного памяти для промежуточного хранилища и времени выполнения, вы можете использовать эту немного более сложную для понимания программу:
Представление
Дано
abc.txt
иmno.txt
с 1 млн несортированных строк по 10 случайных цифр ASCII в каждой (см. Ответ Оли для настройки):против
всего: 23 секунды
источник