Я скопировал массивную папку с компьютера с Windows на компьютер с Linux, и из-за того, что некоторые имена файлов были слишком большими (и некоторые другие ошибки, которые я пропустил), некоторые файлы не могли быть скопированы. В настоящее время я запускаю diff -r между двумя папками, чтобы сгенерировать список файлов, которые находятся в исходной папке, но не в копии. Однако до сих пор единственные вещи, которые он, похоже, распознал, - это отсутствующие папки, то есть кажется, что они пропускают файлы. Есть ли лучший способ для меня, чтобы сделать это сравнение? В частности, я обеспокоен тем, что Bash просто не может распознать эти файлы со слишком длинными именами файлов.
4 ответа
diff <(cd /first/path/ && find ./ | sort) <(cd /second/path/ && find ./ | sort)
Это похоже на этот другой ответ, но:
- Я использую
find
для генерации списков объектов (файлов, каталогов); он подходит здесь лучше, чемls
потому что его вывод содержит только пути. sort
обеспечивает сохранение относительного порядка объектов, независимо от того, в каком порядке каждаяfind
перечисляет их.- Синтаксис
<(…)
позволяет избежать временных файлов вbash
. find
будет выполняться только в том случае, если соответствующийcd
завершится успешно, благодаря оператору&&
. Это избавит вас от запускаfind
в текущем каталоге, если в каком-либо пути есть опечатка.
Дополнительные примечания:
- Пути, возвращаемые функцией
find
будут относиться к каталогам, в которые мыcd
. Убедитесь, что/first/path/
и/second/path/
соответствуют друг другу. - Пустой вывод из
diff
указывает, что две директории идентичны; но помни… - … Команда работает только с путями, она не проверяет соответствие содержимого или метаданных.
- Имена объектов с необычными символами (например, с символами новой строки) нарушат логику.
Вы можете сделать что-то не совсем в отличие от:
(cd some/where; ls -lR) > somewhere.txt
(cd else/where; ls -lR) > elsewhere.txt
diff somewhere.txt elsewhere.txt
Я не пробовал это, это зависит от сохранения метаданных файла (даты и т.д.) (cp -p ...
) и от сортировки файлов ls
в том же порядке (что и должно быть).
Если rsync является жизнеспособной опцией, возможно, будут полезны опции --itemize-changes
(-i) и --dry-run
:
rsync -zaic src_dir/ dest_dir/ --dry-run
-z сжимает файлы во время передачи, -a копирует в режиме архива и -c основывает сравнение файлов на контрольных суммах, а не на дате изменения или размере.
-i перечислит отдельные файлы, которые отличаются, а --dry-run означает, что данные не будут переданы, просто генерируется список.
diff --recursive
(-r
) отлавливает изменения файла, даже в подкаталогах.
Однако вы можете использовать diff --unified --recursive
. Создается унифицированный diff, который отображает измененные строки с префиксом (+) для добавления и (-) для удаления. Удобно, что он также отображает окружающие линии (то есть контекст), так что вы можете выяснить, что там происходит.