Различение двух больших текстовых файлов

32

У меня есть два больших файла (6 ГБ каждый). Они не отсортированы, с переводами строки ( \n) в качестве разделителей. Как я могу их различить? Это должно занять до 24 часов.

jonasl
источник

Ответы:

45

Самый очевидный ответ - просто использовать команду diff, и, возможно, стоит добавить в нее параметр --speed-large-files.

diff --speed-large-files a.file b.file

Вы упоминаете несортированные файлы, поэтому, возможно, вам нужно сначала отсортировать файлы

sort a.file > a.file.sorted
sort b.file > b.file.sorted
diff --speed-large-files a.file.sorted b.file.sorted

Вы можете сохранить создание дополнительного выходного файла, отправив выходные данные 2-й сортировки прямо в diff

sort a.file > a.file.sorted
sort b.file | diff --speed-large-files a.file.sorted -

Очевидно, что они лучше всего будут работать в системе с большим количеством доступной памяти, и вам, вероятно, также понадобится много свободного дискового пространства.

Из твоего вопроса не было ясно, пробовал ли ты это раньше. Если так, то было бы полезно узнать, что пошло не так (слишком долго и т. Д.). Я всегда обнаруживал, что стандартные команды sort и diff имеют тенденцию выполнять как минимум так же хорошо, как и пользовательские команды, если только у файлов нет специфических для домена свойств, которые позволяют делать вещи по-другому.

Richm
источник
2
+1. Вы можете опустить все временные файлы с именованными каналами. Используйте mkfifoдля создания, [ab].file.sortedпрежде чем использовать их в качестве вывода для sort. Поместите оба sortс &в фоновом режиме и используйте оба канала в качестве имен файлов для diff.
Крисси
15
@krissi Вы также можете добиться того же эффекта, используя этот синтаксис:diff <(command 1) <(command 2)
Майкл Мрозек
Спасибо сработало. Мне понадобилась пара ГБ памяти, но 16-ГБ экземпляр Amazon EC2 исправил это :)
jonasl
7
Если кто-то, как я, задается вопросом, почему <(cmd1) <(cmd2)работает синтаксис (как будто он дважды перенаправляет стандартный ввод!), Попробуйте echo hello <(cmd1) <(cmd2). Вы увидите что-то вроде этого, hello /dev/fd/63 /dev/fd/62которое внезапно проясняет;)
alex
3
По моему опыту --speed-large-filesопция не помогает, если у вас недостаточно оперативной памяти. Кроме того, предварительная сортировка не помогает, если у вас есть многострочная структура записи, которую вы хотите сохранить. Опции, упомянутые выше (автор @unhammer), интересны, но вывод от rdiffи bsdiffявляется скорее двоичным. Установка bdiffиз Heirloom Toolbox выглядит как задача даунинга (требуется Heirloom devtools, вымершие заголовочные файлы,…). Это действительно стоит усилий? Есть ли другие альтернативы?
Кристиан Питч
5

Сортировка входных данных и сообщение diffпрограмме, что входные данные отсортированы, обеспечат значительное ускорение. Я не знаю ни одного diffс такой опцией, но commпредполагает сортированный ввод и будет гораздо быстрее, если этого будет достаточно для ваших целей.

Карл
источник
commотлично работал для этого, никогда не слышал об этом раньше, но, видимо, его в coreutils.
theferrit32