Как сравнить две папки и скопировать разницу в третью папку?

23

У вас есть три папки:

  • папка current , в которой находятся ваши текущие файлы
  • папка old , которая содержит более старую версию тех же файлов
  • разница папок , которая является просто пустой папкой

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


Я искал все вокруг, и мне кажется, что это просто, но я не могу заставить его работать в моем конкретном примере. Большинство источников предлагали использовать rsync, поэтому в итоге я выполнил следующую команду:

rsync -ac --compare-dest=../old/ new/ difference/

Однако он копирует все файлы с нового на различие , даже те, которые совпадают со старыми .

В случае, если это помогает (возможно, команда в порядке, и ошибка лежит в другом месте), вот как я это проверил:

  1. Я сделал три папки.
  2. Я сделал несколько текстовых файлов с различным содержанием в старом .
  3. Я скопировал файлы из старого в новый .
  4. Я изменил содержимое некоторых файлов в новые и добавил несколько дополнительных файлов.
  5. Я запустил указанную выше команду и проверил результаты на разницу .

Я искал решение в течение последних нескольких дней, и я очень признателен за помощь. Не обязательно использовать rsync, но я хотел бы знать, что я делаю неправильно, если это возможно.

тан
источник
Возможный дубликат Как я могу сохранить измененные файлы?
wingedsubmariner
@wingedsubmariner Я не думаю, что это дубликат, поскольку принятый ответ на связанный вопрос - это команда, о которой ОП задает вопрос.
Бернхард
@ Бернхард Ах, мой плохой. Думаю, я неправильно понял исходный вопрос.
wingedsubmariner
@wingedsubmariner Не беспокойтесь, вы сказали «возможно», и я согласен, что это выглядит очень похоже :)
Бернхард

Ответы:

7

Я не уверен, можете ли вы сделать это с любыми существующими командами linux, такими как rsync или diff. Но в моем случае мне пришлось написать свой собственный скрипт с использованием Python, так как в python есть модуль filecmp для сравнения файлов. Я разместил весь сценарий и использование на моем личном сайте - http://linuxfreelancer.com/

Его использование простое - укажите абсолютный путь к новому каталогу, старому каталогу и каталогу различий в указанном порядке.

#!/usr/bin/env python

import os, sys
import filecmp
import re
from distutils import dir_util
import shutil
holderlist=[]

def compareme(dir1, dir2):
    dircomp=filecmp.dircmp(dir1,dir2)
    only_in_one=dircomp.left_only
    diff_in_one=dircomp.diff_files
    dirpath=os.path.abspath(dir1)
    [holderlist.append(os.path.abspath( os.path.join(dir1,x) )) for x in only_in_one]
    [holderlist.append(os.path.abspath( os.path.join(dir1,x) )) for x in diff_in_one]
    if len(dircomp.common_dirs) > 0:
        for item in dircomp.common_dirs:
            compareme(os.path.abspath(os.path.join(dir1,item)), os.path.abspath(os.path.join(dir2,item)))
        return holderlist

def main():
 if len(sys.argv) > 3:
   dir1=sys.argv[1]
   dir2=sys.argv[2]
   dir3=sys.argv[3]
 else:
   print "Usage: ", sys.argv[0], "currentdir olddir difference"
   sys.exit(1)

 if not dir3.endswith('/'): dir3=dir3+'/'

 source_files=compareme(dir1,dir2)
 dir1=os.path.abspath(dir1)
 dir3=os.path.abspath(dir3)
 destination_files=[]
 new_dirs_create=[]
 for item in source_files:
   destination_files.append(re.sub(dir1, dir3, item) )
 for item in destination_files:
  new_dirs_create.append(os.path.split(item)[0])
 for mydir in set(new_dirs_create):
   if not os.path.exists(mydir): os.makedirs(mydir)
#copy pair
 copy_pair=zip(source_files,destination_files)
 for item in copy_pair:
   if os.path.isfile(item[0]):
    shutil.copyfile(item[0], item[1])

if __name__ == '__main__':
 main()
Даниил Т.
источник
21

Я понял, в чем проблема в моем случае:

Файлы, которые я сравнивал, имели разные временные метки. Я не должен был использовать аргумент -a , я полагаю, потому что rsync пытался сохранить метки времени при копировании файлов. Команда, которая работала для меня, была:

rsync -rvcm --compare-dest=../old/ new/ difference/
тан
источник
Я думаю, чтобы проверить это с опцией -a (архив), вы должны были rsync -aсначала «скопировать» файлы (или эквивалент cp), затем удалить или изменить. (Мне нравится придерживаться rsync, потому что я знаю, что он самосогласован, не задумываясь о том, что он может делать.) Я думаю, что это должно было работать с оригинальной командой. Опция -a включает -t (сравнение по метке времени), которая является альтернативой -c (сравнение по контрольной сумме).
мудрец
2
На мой взгляд, этот ответ должен быть принят, так как он намного проще. Кроме того, команда работала только для меня, когда я указывал полный путь для old/и new/.
Яманеко
Похоже, предостережение заключается в том, что сравнение-dest должно быть относительным путем к разнице, видимой изнутри фактического dest
Райан Уильямс
1

Это могло бы помочь некоторым читателям: в Windows старая, немного бесплатная программа - Third Dir - делает именно то, о чем здесь просят. Это больше не доступно через разработчика, Роберта Вашика. Но я уверен, что это можно найти через некоторые репозитории онлайн.

Вот описание разработчика, которое остается на его сайте:

Third Dir: необычный каталог-синхронизатор - разные файлы копируются в третий каталог. Очень полезно извлечь, например, новые или отредактированные фотографии из огромного дерева каталогов на фиксированном диске во временную папку, а затем добавить их на архивный компакт-диск (обратите внимание - исходные файлы сравниваются с компакт-диском). Версия 1.4, размер 23 КБ. Создано 2005-02-12.

История: версия 1.14 - более эффективна при сравнении десятков тысяч файлов.

Стив
источник
0

Способ rsync, данный Тейном с дополнениями Yamaneko, прекрасно работает, но оставляет пустые каталоги. Для меня окончательное решение состояло из двух шагов: сначала вызовите rsync с полным путем, а затем команду find, чтобы удалить все пустые каталоги:

rsync -rvcm --compare-dest=/tmp/org/ /tmp/new/ /tmp/difference/
find /tmp/difference/ -d -type d -empty -exec rmdir {} \; -print

Обратите внимание, что даже с параметром --links, rsync не сохранил символические ссылки, а скопировал данные назначения.

Pierrel
источник
Обратите внимание, что вместо -empty -exec rmdir {} \;вас можно использовать -empty -delete.
mivk
-3

Я использую двухпанельный XY Explorer (коммерческий), который может делать много трюков, и это один из них. Откройте Currentв одной панели и Старый в другой. Активируйте текущую панель. Перейдите в Панели > Выбор синхронизации . Это дает вам 5 вариантов на выбор:

  1. Матчи (перечислены в обоих)
  2. Уникальность (в активной панели)
  3. Новее (в активной панели)
  4. Уникальные и новые файлы (в активной панели)
  5. Выбранный (выбранный на другой панели)

Теперь вы можете скопировать полученную выборку Currentтуда, куда хотите. Я использовал его для сравнения mailfoldersстарых версий с последними. Структура папок была довольно сложной, но (почти) все mbs-filesимели уникальный номер.

Поэтому я выполнил поиск mbs-filesв старом корне mailfolder(на одной панели), а также на самой новой (на другой панели) и провел сравнение результатов поиска на каждой панели ( Синхронизация выбора уникальных , чтобы найти пропавшие письма во время поиска). переустанавливает)! Вы можете установить много вариантов тоже.

Мартейн Доувес
источник
1
Если вы говорите о нестандартном программном обеспечении, вы должны включить ссылку. Если вы имеете в виду XYplorer, то это никак не поможет OP.
Anthon