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

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

Я не могу запустить 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 найти нужные папки?

1 ответ1

2

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

Как уже указывалось, 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). Если ваши два каталога хранятся в разных файловых системах с разной точностью дат, вам, возможно, придется использовать другой (ручной) формат даты, чтобы исключить доли секунды.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .