Вопрос или проблема
В контексте командной строки Unix я хотел бы сравнить два действительно огромных файла (около 1 ТБ каждый), желательно с индикатором прогресса.
Я пробовал diff
и cmp
, и оба они зависали, что приводило к сбоям системы (macOS Mojave), не говоря уже о том, что я не получал индикатор прогресса.
Какой лучший способ сравнить эти очень большие файлы?
Дополнительные детали:
-
Я просто хочу проверить, идентичны ли они.
-
cmp
зависал так, что система перезагружалась сама. 🙁 Может быть, системе не хватало памяти?
Вы можете использовать pv
как индикатор прогресса и передать это в функцию shasum
для проверки хеша, чтобы выяснить, идентичны ли они.
pv file1 | shasum
1.08MiB 0:00:00 [57.5MiB/s] [====================================>] 100%
303462e848ecbec5f8ab12718fa6239713eda1c6 -
pv file2 | shasum
1.08MiB 0:00:00 [57.5MiB/s] [====================================>] 100%
303462e848ecbec5f8ab12718fa6239713eda1c6 -
Если вы хотите получить информацию о том, идентичны ли файлы, одним из возможных способов является использование хеша. Команда вроде этой даст вам sha1
хеш файлов:
shasum file1 file2
Ожидаемый результат выглядит примерно так:
ddfdb3a7fc6fc7ca714c9e2930fa685136e90448 file1
ddfdb3a7fc6fc7ca714c9e2930fa685136e90448 file2
Вы могли бы оценить общее время, убирая по несколько ГБ из каждого файла, замеряя время, а затем пропорционально масштабируя. Индикатор прогресса также должен считать байты — он может увеличить время на 50% сам по себе.
На самом деле, вы можете использовать цикл, чтобы разделить файлы на 100 секций (используя dd
, или head -c
+ tail -c
с пайпами), использовать ваш предпочтительный инструмент сравнения и отчитываться о каждой секции.
Преимущества
-
Предоставляет отчет о прогрессе с интервалом 1%.
-
Если различия наблюдаются на раннем этапе, вы получите ответ раньше и сможете выйти из цикла, не проверяя остальные части файла.
-
Сравнение файлов по 10 ГБ, вероятно, не перезагрузит вашу систему.
-
Вы можете адаптировать это для более детального анализа известных областей файла: делите и властвуйте.
-
Вы можете назначить секции адресного диапазона нескольким процессорам.
MD5
В зависимости от вашего оборудования, md5sum
может вероятно быть быстрее. В некоторых тестах он был на около 30% быстрее. Также, по какой-то причине (размеры блоков?), пайпинг с pv
кажется на около 20% быстрее.
pv file | md5sum
Коллизия: Для простого сравнения двух файлов вероятность коллизии чрезвычайно низка. Если сравнивать по два в час, мы могли бы ожидать увидеть первую коллизию примерно через 1 квадрильон лет.
Тесты
Попробуйте openssl speed md5 sha1
, или
-
Найдите ваши самые большие файлы:
find ~ -type f -printf '%s %p\n' | sort -nr | head file="bigest_file"
-
Проведите несколько тестов несколько раз (чтобы снизить кэш-проблемы)
time md5sum $file; time shasum $file; time md5sum $file; time shasum $file; \ time pv $file | md5sum; time pv $file | sha1sum; time pv $file | md5sum; time pv $file | sha1sum
Я использую:
pv file1 | cmp file2
Только что использовал это для нескольких многотерабайтных файлов на своем компьютере с Ubuntu, и это работает отлично, и, вероятно, является самым быстрым вариантом, потому что оно читает оба файла одновременно.
root@server:/folder1# pv /folder1/filename | cmp /folder2/filename
5.62TiB 9:38:09 [ 149MiB/s] [======================> ] 51% ETA 9:05:08
Проблема с cmp
состоится, вероятно, в какой-то другой проблеме с вашим ПК.
Ответ или решение
Чтобы сравнить большие файлы (около 1 ТБ каждый) в среде командной строки Unix, лучше всего использовать методы, которые обеспечивают индикацию прогресса и избегают чрезмерного использования памяти. Предлагаю несколько подходов к решению этой задачи.
1. Использование хеширования
Одним из наиболее надежных способов проверки идентичности файлов является использование хеш-функций. Вы можете воспользоваться инструментами, такими как shasum
или md5sum
, для вычисления хешей двух файлов и сравнения их значений.
Пример команд:
pv file1 | shasum
pv file2 | shasum
Эти команды обеспечат прогресс-индикацию при вычислении хеша.
Для более прямого сравнения двух файлов, можно использовать:
shasum file1 file2
Ожидаемый результат будет выглядеть следующим образом, если файлы идентичны:
ddfdb3a7fc6fc7ca714c9e2930fa685136e90448 file1
ddfdb3a7fc6fc7ca714c9e2930fa685136e90448 file2
2. Сравнение с учетом прогресса
Если вы хотите сравнить два файла и видеть прогресс, вы можете использовать pv
вместе с cmp
, что позволяет читать оба файла одновременно.
Пример команды:
pv file1 | cmp file2
Эта команда будет отображать информацию о прогрессе, что позволяет контролировать, насколько далеко вы продвинулись в процессе сравнения.
3. Деление файлов на секции
Если вы хотите оптимизировать процесс, можно разбить файлы на части и сравнивать их секциями. Это также поможет вам отслеживать прогресс и, возможно, завершить операцию раньше, если будет обнаружено, что файлы различаются.
Пример процесса:
- Используйте команду
dd
,head
, илиtail
, чтобы разбить файлы на части. - Сравните каждую часть, используя
shasum
,md5sum
, или любые другие инструменты.
Преимущества такого подхода:
- Позволяет получать отчеты о прогрессе в процентах.
- При обнаружении различий раннее прекращает проверку остальных частей, экономя время.
- Сравнение меньших по размеру файлов снизит вероятность перегрева системы или нехватки памяти.
4. Производительность хеширования
В некоторых случаях md5sum
может быть быстрее, чем хеширование с помощью SHA, поэтому вы можете провести тесты производительности:
openssl speed md5 sha1
А затем измерить время работы для различных файлов.
Заключение
Выбор метода сравнения зависит от ваших предпочтений и доступных ресурсов. Используйте хеширование для надежности и pv
для индикации прогресса. Сравнение больших файлов может быть ресурсоемким процессом, поэтому следите за нагрузкой на систему и в случае проблем с памятью рассматривайте возможность разбивки файлов на меньшие части.