Как рекурсивно сравнить две папки и создать список файлов и папок, которые отличаются?
тл; др и пример
Я ищу способ рекурсивного сравнения двух папок и вывода относительных путей ко всем файлам (и папкам), которые отличаются (по размеру или по метке времени, как rsync).
Например, скажем, у меня есть
C:\source\foo\a.txt
C:\source\foo\bar\b.txt
C:\source\foo\bar\c.txt
а также
C:\target\foo\a.txt
C:\target\foo\bar\b.txt
C:\target\foo\bar\d.txt
C:\target\foo\baz\
и предположим b.txt
был изменен в соответствии с C:\source
и, таким образом, новее.
Затем, используя магический сценарий или команду, скажем, magic C:\source C:\target
Я хотел бы, чтобы вывод был
foo\bar\b.txt
Или полный путь к исходной или целевой папке тоже будет приемлемым:
C:\source\foo\bar\b.txt
Как показывает пример, меня не волнуют файлы и папки, которые были удалены или созданы! Что должно сделать эту задачу намного проще, чем иначе.
Что я уже знаю...
Я сам разработчик UNIX и не спрашиваю, была ли это система UNIX, с которой мы имеем дело, но увы. Кроме того, это для нестандартного решения ночного резервного копирования, где надежность и целостность данных являются приоритетом, поэтому, учитывая, что несколько недель назад я даже не мог выяснить цикл for в пакетном скрипте, я почти уверен, что мне не хватает опыт, чтобы сделать это правильно, или даже определить лучший способ сделать это.
Читая http://www.howtoforge.com/backing-up-with-rsync-and-managing-previous-versions-history, я узнал, что rsync может делать что-то вроде того, что мне нужно, используя такие параметры, как
--dry-run # don't actually rsync (touch) any files
--itemize-changes # list changes rsync _would_ have made
--out-format="%i|%n|" # define an output format for the list of changes
Однако я не хотел бы полагаться на то, что Cygwin (cwRsync) будет использовать rsync, так как я уже склонен к проведению быстрых и грязных экспериментов с моей установкой Cygwin, часто нарушая среду и требуя переустановки Cygwin каждые несколько недель. Такого рода противопоставление "надежной" части ночной резервной копии.
Я не нашел ни одного "канонического" инструмента, такого как rsync, в Windows, по крайней мере, такого, который бы поддерживал опции, подобные приведенным выше. Кроме того, я не ищу программное обеспечение вообще, если это не простой и компактный инструмент специально для этой цели -я предпочитаю прозрачное, программное решение. Для чего-то столь же важного, как резервное копирование файлов, полагаться на программное обеспечение или код, который я не вижу или не понимаю, страшно!
резюмировать
Я не могу обернуть голову вокруг синтаксиса пакетного сценария. Далее я попробую PowerShell. Но что бы вы сделали, если бы выполнили эту задачу? - Есть ли какой-то очевидный маршрут, по которому я скучаю?
2 ответа
@Glytzhkof рекомендовал Robocopy в своем ответе, и он полностью соответствовал моим потребностям.
ТЛ; др
C:\>robocopy.exe source target /l /e /zb /xx /xl /fp /ns /nc /ndl /np /njh /njs
C:\source\foo\bar\b.txt
Детали и объяснение опций
Robocopy (Wikipedia), кажется, широко применяется для системного администрирования Windows; хорошо документирован (TechNet); обсуждается как нечто большее, чем неясность о переполнении стека, сбое сервера и, конечно же, здесь, в Super User; обеспечивает определенную функцию, а не пытается быть многоцелевым инструментом (который имеет тенденцию к вздутию живота и ошибкам); и, кроме того, выполняет эту конкретную функцию с 1997 года. Для меня все эти факторы способствуют "прозрачности", несмотря на то, что она является закрытым исходным кодом, и успокаивают меня.
Robocopy входит в состав набора инструментов, которые в настоящее время называются Windows Server 2003 Resource Kit Tools. После загрузки и установки я воссоздал сценарий в своем вопросе и попробовал:
C:\>robocopy.exe source target /l /e /zb
-------------------------------------------------------------------------------
ROBOCOPY :: Robust File Copy for Windows
-------------------------------------------------------------------------------
Started : Thu May 01 09:08:20 2014
Source : C:\source\
Dest : C:\target\
Files : *.*
Options : *.* /L /S /E /COPY:DAT /ZB /R:1000000 /W:30
------------------------------------------------------------------------------
0 C:\source\
1 C:\source\foo\
*EXTRA Dir -1 C:\target\foo\baz\
2 C:\source\foo\bar\
*EXTRA File 1 d.txt
Newer 5 b.txt
New File 1 c.txt
------------------------------------------------------------------------------
Total Copied Skipped Mismatch FAILED Extras
Dirs : 3 0 3 0 0 1
Files : 3 2 1 0 0 1
Bytes : 7 6 1 0 0 1
Times : 0:00:00 0:00:00 0:00:00 0:00:00
Ended : Thu May 01 09:08:20 2014
Выглядит хорошо! Позвольте мне объяснить варианты:
/l
перечисляет действия, фактически не выполняя их./e
включает в себя подкаталоги, но в отличие от/s
, также включает в себя пустые каталоги./zb
копирование в режиме "перезагрузки" и при отказе в доступе в режиме "резервного копирования"; похоже, самый безопасный подход; читайте больше здесь.
Мне не нужны были какие-либо опции, связанные с копированием, поскольку я фактически не выполняю никаких действий.
Во всяком случае, дальше, нужно было только добавить больше переключателей, чтобы получить желаемый результат:
C:\>robocopy.exe source target /l /e /zb /xx /xl /fp /ns /nc /ndl /np /njh /njs
C:\source\foo\bar\b.txt
Опять пройдемся по вариантам.
Во-первых, я заботился только об измененных файлах и папках, поэтому:
/xx
исключает "лишние" файлы и каталоги - те, которые существуют только в цели./xl
исключает "одинокие" файлы и каталоги - те, которые существуют только в источнике.
Во-вторых, я хотел относительные пути (или, по крайней мере, полные пути, а не только имена):
/fp
включает полные пути (что неудивительно, что не было опции для относительных путей).
В-третьих, я хотел удалить как можно больше бревен, и был приятно удивлен, обнаружив, что все это можно удалить:
/ns
подавляет размеры файлов./nc
подавляет занятия, напримерNewer
,/ndl
подавляет имена каталогов./np
подавляет вывод прогресса копирования./njh
подавляет заголовок задания./njs
подавляет резюме работы.
И вот оно!
Для моих целей (создание версированных резервных копий измененных файлов) я понял, что на самом деле мне бы тоже хотелось иметь временную метку для каждого измененного файла. Просто добавь /ts
:
C:\>robocopy.exe source target /l /e /zb /xx /xl /fp /ns /nc /ndl /np /njh /njs /ts
2014/05/01 15:20:42 C:\source\foo\bar\b.txt
Однажды я создал пользовательскую систему резервного копирования с пакетным управлением, в которой был установлен инструмент стороннего производителя, который каждую ночь копировал новые и измененные файлы на диск резервного копирования. Что касается моей жизни, я не могу вспомнить, как назывался этот инструмент в данный момент. Я мог бы найти это, но не сейчас.
Лучшим дешевым, коммерческим инструментом сравнения является Beyond Compare с http://www.scootersoftware.com/ - это превосходный инструмент. Его полезность незамедлительна, и каждый профессионал, работающий с файлами, получит пользу от этого каждый день. Попробуй это. Смотрите скриншот. Существует версия для командной строки.
Кроме этого Robocopy.exe должен быть в состоянии выполнить то, что вы хотите, с некоторым терпением и тестированием.
Еще один совет: чтобы избежать аварийного резервного копирования, я запустил сценарий резервного копирования с учетной записью с низким уровнем привилегий, чтобы предотвратить удаление чего-либо, если кто-то будет связываться со сценарием или вообще иметь какие-либо права, если кто-то попытается войти в него. Я думаю, что я установил неинтерактивную учетную запись или не смог войти в систему в интерактивном режиме или что-то. Настоятельно рекомендуем это для пакетной работы в Windows. Просто подумал, что упомяну это, так как вы пришли из мира Unix.