Как рекурсивно сравнить две папки и создать список файлов и папок, которые отличаются?

11227
Andrew Cheong

тл; др и пример

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

5
Многие люди используют winmerge для этого, но ваши выходные данные будут сложно скопировать, если вы не создадите свой собственный скрипт. Frank Thomas 10 лет назад 1

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

4
Andrew Cheong

@Glytzhkof recommended Robocopy in his answer, and it suited my needs perfectly.

tl;dr

C:\>robocopy.exe source target /l /e /zb /xx /xl /fp /ns /nc /ndl /np /njh /njs C:\source\foo\bar\b.txt 

Details & Explanation of Options

Robocopy (Wikipedia) seems widely adopted for Windows system administration; is well-documented (TechNet); is discussed as more than an obscurity on Stack Overflow, Server Fault, and of course, here at Super User; provides for a specific function rather than trying to be a multi-purpose tool (which tend toward bloat and bugs); and furthermore has been providing this specific function since 1997. For me, all these factors contribute to "transparency," despite it being closed-source, and set my mind at ease.

Robocopy comes as part of a set of tools currently known as Windows Server 2003 Resource Kit Tools. After downloading and installing, I recreated the scenario in my question and gave it a go:

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 

Looks good! Let me explain the options:

  • /l lists actions without actually carrying them out.
  • /e includes subdirectories, but unlike /s, includes empty directories too.
  • /zb copies in "restart" mode, and on access denied, "backup" mode; it seems like the safest approach; read more here.

I didn't need any of the copy-related options since I'm not actually performing any actions.

Anyway, next, it was only a matter of adding more switches to get the output I desired:

C:\>robocopy.exe source target /l /e /zb /xx /xl /fp /ns /nc /ndl /np /njh /njs C:\source\foo\bar\b.txt 

Again, let's go through the options.

First, I only cared about modified files and folders, so:

  • /xx excludes "extra" files and directories—those which exist only in the target.
  • /xl excludes "lonely" files and directories—those which exist only in the source.

Second, I desired relative paths (or at least full paths, not just names):

  • /fp enables full paths (unsurprisingly, there was no option for relative paths).

Third, I wanted to remove as much logging fluff as possible, and I was pleasantly surprised to find that all of it was removable:

  • /ns suppresses file sizes.
  • /nc suppresses classes, e.g. Newer.
  • /ndl suppresses directory names.
  • /np suppresses copy progress output.
  • /njh suppresses the job header.
  • /njs suppresses the job summary.

And there you have it!


For my purposes (creating versioned backups of changed files), I realized I'd actually like to have the timestamp of each modified file, too. Simply add /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 
2
Stein Åsmul

I made a custom batch driven backup system once that had a third party tool copying new and changed files to a backup drive nightly. For my life I can't recall what the name of that tool was at this point. I might be able to find it, but not right now.

The best cheap, commercial comparison tool out there is Beyond Compare from http://www.scootersoftware.com/ - it is hands down a brilliant tool. Its usefulness is immediate and a tool all professionals working with files would benefit from every day. Try it. See a screenshot. There is a command line version included.

Other than that Robocopy.exe should be able to accomplish what you want with some patience and testing.

Another tip: to avoid backup disaster I ran the backup script with a low-priviledge account to prevent it from deleting anything if someone would mess with the script, or have any rights at all if someone tries to log on with it. I think I set the account non-interactive or unable to log on interactively or something. Highly recommend this for batch running on Windows. Just thought I'd mention it since you are coming from the world of Unix.

Уже +1 добавил ваш ответ; Спасибо! `robocopy.exe` работает очень хорошо! Надеюсь, вы не будете возражать, если я отправлю и приму свой более подробный ответ. Andrew Cheong 10 лет назад 0

Похожие вопросы