Як ви порівнюєте дві папки та копіюєте різницю в третю папку?


23

У вас є три папки:

  • поточна папка , яка містить ваші поточні файли
  • папка стара , яка містить старішу версію тих же файлів
  • різниця папок , яка є лише порожньою папкою

Як ви порівнюєте старі з поточними та копіюєте файли, які є різними (або абсолютно новими) у поточному, на різницю ?


Я шукав все навколо, і це здається простою справою, але я не можу змусити його працювати на моєму конкретному прикладі. Більшість джерел пропонували використовувати rsync, тому я закінчив наступну команду:

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

Однак це є копією всіх файлів із нових на різницю , навіть тих, що є такими, як у старих .

У випадку, якщо це допомагає (можливо, команда нормальна, а помилка полягає в іншому місці), ось як я це перевірив:

  1. Я зробив три папки.
  2. Я зробив кілька текстових файлів з різним вмістом у старому .
  3. Я скопіював файли зі старого в новий .
  4. Я змінив вміст деяких файлів на нові та додав кілька додаткових файлів.
  5. Я запустив вищезгадану команду і перевірив результати на відмінність .

Я шукав рішення останні кілька днів, і я дуже вдячний за допомогу. Це не обов’язково використовувати rsync, але я хотів би знати, що я роблю неправильно, якщо можливо.



@wingedsubmariner Я не думаю, що це дублікат, оскільки прийнята відповідь на пов'язане питання - це команда, про яку ОП задає питання.
Бернхард

@Bernhard Ах, моє погано. Напевно, я неправильно зрозумів початкове запитання.
wingedsubmariner

@wingedsubmariner Не хвилюйтесь, ви сказали "можливо", і я згоден, це дуже схоже :)
Bernhard

Відповіді:


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/.
Яманеко

Застереження здається, що ціль порівняння повинна бути відносним шляхом до різниці, яку видно всередині фактичної мети
Райан Вільямс

1

Це може допомогти деяким читачам: У Windows стара, маленька безкоштовна програма - Третій Dir - робить саме те, про що тут просять. Він більше не доступний через розробника, Роберт Ванік. Але я впевнений, що його можна знайти через деякі сховища в Інтернеті.

Ось опис розробника, який залишається на його сайті:

Третій Dir: Незвичайний каталог-синхронізатор - різні файли копіюються в третій каталог. Дуже корисно витягнути, наприклад, нові чи відредаговані фотографії з величезного дерева каталогів на фіксованому диску до тимчасової папки, а потім додати їх до архіву компакт-диска (зверніть увагу - оригінальні файли порівнюються з компакт-диском). Версія 1.4, розмір 23 кБ. Створено 2005-02-12.

Історія: Версія 1.14 - Більш ефективно, коли порівнюється багато десяти тисяч файлів.


0

Спосіб rsync, наданий Thane з доповненнями 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 не зберігав символічні посилання, а скопіював дані призначення.


Зауважте, що замість -empty -exec rmdir {} \;вас можна використовувати -empty -delete.
mivk

-3

Я використовую dualpane XY Explorer (комерційний), який може робити багато хитрощів, і це один із них. Відкрийте Currentв одній панелі, а Стару - в іншій. Активуйте поточну панель. Перейдіть до панелей > Вибрати синхронізацію . Це дає 5 варіантів для вибору:

  1. Матчі (вказані в обох)
  2. Унікальні елементи (в активній області)
  3. Новіше (в активній області)
  4. Унікальні та новіші файли (на активній панелі)
  5. Вибрано (вибрані в іншій області)

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

Тож я здійснив пошук як mbs-filesу старому корені mailfolder(на одній панелі), так і по новітньому (на іншій панелі) і порівняв результати пошуку на кожній панелі ( Sync Select Unique , щоб знайти пошти, які пропали протягом перевстановлення)! Ви також можете встановити безліч варіантів.


1
Якщо ви говорите про нестандартне програмне забезпечення, вам слід включити посилання. Якщо ви маєте на увазі XYplorer , це зовсім не збирається допомогти ОП.
Антон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.