использовать diff для текстовых файлов со списком файлов, чтобы найти разные файлы по размеру и / или измененной дате / времени

315
IMTheNachoMan

Мне нужно сравнить две папки, чтобы найти файлы, которые либо:

  • другой размер и / или измененная дата / время
  • отсутствует от одного

Я не могу запустить diffдве папки в моей ситуации. Я планировал использовать findобе папки и сохранить выходные данные в два текстовых файла, а затем сравнить два текстовых файла, используяdiff .

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

Если две папки точно такие же, я предполагаю, что это будет работать. Но я сомневаюсь, что произойдет, если в одной папке будет много более сложных подкаталогов / файлов. Будетdiff понять структуру печати папки вывода?

Например, я проведу инвентаризацию папки за один день.

$ find /path/to/folder -exec ls -ld {} \; > inventory-20181101.txt ... 

Я буду изменять кучу вещей, включая добавление, удаление, редактирование файлов и добавление или удаление папок и подпапок. Тогда в другой день я возьму другой инвентарь.

$ find /path/to/folder -exec ls -ld {} \; > inventory-20181102.txt ... 

Тогда я буду различать два файла.

$ diff inventory-20181101.txt inventory-20181102.txt 

Я предполагаю, что это будет работать, если не было никаких изменений или изменения были незначительными, как просто изменение файлов. Но что произойдет, если я добавлю в нее 5 уровней вложенных папок, а затем 100 файлов и удалю еще одну папку верхнего уровня. Сможете ли diffвы подобрать нужные папки?

0
Обратите внимание, что https://superuser.com не является бесплатным сервисом для написания скриптов / кодов. Если вы сообщите нам, что вы уже пробовали (включая скрипты / код, который вы уже используете) и где вы застряли, мы можем попытаться помочь с конкретными проблемами. Вам также следует прочитать [Как мне задать хороший вопрос?] (Https://superuser.com/help/how-to-ask). DavidPostill 5 лет назад 1
@DavidPostill Я не прошу никого писать сценарий для меня. Я спрашиваю, как работает `diff` и сможет ли он понять различия в структурах папок, сохраненных в текстовом файле. Я поставлю более подробно в моем вопросе. Спасибо! IMTheNachoMan 5 лет назад 1
(1) `find` не гарантирует перечисление файлов в каталоге в каком-либо определенном порядке. Если вы запустите его два раза подряд, это, вероятно, даст те же результаты, но после месяцев осмотра в дереве каталогов, скорее всего, все изменится. Файлы, которые не были изменены каким-либо образом, могут быть в том же относительном порядке, но я сомневаюсь, что даже это гарантировано. (2) `diff` печально известен тем, что не выполняет" повторную синхронизацию "после больших изменений, поэтому он может сообщать о некоторых неизмененных строках как об удаленных, так и о вставленных. Вероятно, он не пропустит никаких изменений. Scott 5 лет назад 2
Как насчет того, чтобы просто попробовать его на фиктивной папке, чтобы проверить варианты? Создайте пару примеров каждой вещи, которая вас волнует, и посмотрите, как работает ваш подход. Если это справится с ситуацией, количество не изменит это. fixer1234 5 лет назад 2
@ fixer1234 Я провел несколько тестов, и это сработало, но я хочу быть уверенным, что оно будет работать для больших папок с миллионами файлов. Из комментария Скотта звучит так, что `find` и` diff` не будут для меня надежными. IMTheNachoMan 5 лет назад 0
@ Скотт Спасибо! Это помогает мне. Мне нужно будет найти лучший способ сделать то, что я хочу. IMTheNachoMan 5 лет назад 0

1 ответ на вопрос

2
n.st

Чтобы получить надежный обзор, вам понадобятся единые и сортируемые списки файлов в обоих каталогах и способ сравнения этих двух списков.

Как уже указывалось, diffпредназначен для создания удобочитаемых, семантически понятных обзоров различий между файлами. Это делает его очень подходящим для сравнения простого текста или кода, но менее подходящим для сравнения списков.
Вместо этого используйте, commчтобы найти сходства или различия между двумя списками.

Чтобы создать «чистый» список, который содержит только ту информацию, которая вам нужна, используйте -printfопцию, предоставляемую GNU find. Это более эффективно и надежно, чем порождение lsпроцесса для каждого файла, и может напрямую выводить полезную информацию, такую ​​как:

  • %Tk File's last modification time in the format specified by k
  • %s File's size in bytes
  • %p File's name

Собираем все вместе:

  1. Перечислите файлы в каждом каталоге (в формате, который содержит только необходимую информацию) → find … -printf …
  2. Сортировать списки → sort
  3. Найти все строки, которые не совпадают между списками → comm -3: «подавить столбец 3 (строки, которые появляются в обоих файлах)»
 cd dir1 && find . -printf '%T+ %s %p\n' | sort > ../dir1.txt && cd .. cd dir2 && find . -printf '%T+ %s %p\n' | sort > ../dir2.txt && cd .. comm -3 dir1.txt dir2.txt > differences.txt 

Одно предупреждение с %T+: формат даты будет включать доли секунды (2018-11-25 + 14: 58: 43.1197033990). Если ваши два каталога хранятся в разных файловых системах с разной точностью дат, вам, возможно, придется использовать другой (ручной) формат даты, чтобы исключить доли секунды.

Это фантастическая информация. Я дам это попробовать. Спасибо вам большое! IMTheNachoMan 5 лет назад 0
Использование `find… -printf`,` sort` и `comm` - хорошие идеи. Пара небольших заметок: (1) Вышеуказанные сортировки по времени модификации. Сортировка по имени файла может быть более удобной для пользователя. (2) Как всегда, при обработке вывода `find`, вы можете столкнуться с проблемами с файлами, имена которых содержат символ новой строки. Файлы, имена которых содержат пробел или табуляцию *, могут * также быть проблемой, особенно если они * начинаются * с пробела или табуляции. (Я должен был упомянуть об этом в [моем первом комментарии] (https://superuser.com/q/1377900/150988#comment2077322_1377900).) Scott 5 лет назад 0