GNU/Linux >> Znalost Linux >  >> Linux

Existuje způsob, jak synchronizovat strukturu adresářů, když jsou soubory již na obou stranách?

Mám dva disky se stejnými soubory, ale struktura adresářů je úplně jiná.

Existuje nějaký způsob, jak „přesunout“ všechny soubory na cílové straně tak, aby odpovídaly struktuře zdrojové strany? Možná se skriptem?

Například jednotka A má:

/foo/bar/123.txt
/foo/bar/234.txt
/foo/bar/dir/567.txt

Zatímco jednotka B má:

/some/other/path/123.txt
/bar/doo2/wow/234.txt
/bar/doo/567.txt

Dotyčné soubory jsou obrovské (800 GB), takže je nechci znovu kopírovat; Chci pouze synchronizovat strukturu vytvořením potřebných adresářů a přesunem souborů.

Přemýšlel jsem o rekurzivním skriptu, který by našel každý zdrojový soubor v cíli, pak jej přesunul do odpovídajícího adresáře a v případě potřeby jej vytvořil. Ale — to je nad mé schopnosti!

Další elegantní řešení bylo uvedeno zde:
https://superuser.com/questions/237387/any-way-to-sync-directory-structure-when-the-files-are-already-on-both-sides /238086

Přijatá odpověď:

Půjdu s Gillesem a nasměruji vás na Unison, jak navrhl hasen j. Unison byl DropBox 20 let před DropBoxem. Pevný kód, který mnoho lidí (včetně mě) používá každý den – velmi stojí za to se ho naučit. Přesto se join potřebuje veškerou publicitu, kterou může získat 🙂

Toto je jen poloviční odpověď, ale musím se vrátit do práce 🙂

V podstatě jsem chtěl demonstrovat málo známé join nástroj, který dělá právě to:spojuje dvě tabulky na nějakém poli.

Nejprve nastavte testovací případ obsahující názvy souborů s mezerami:

for d in a b 'c c'; do mkdir -p "old/$d"; echo $RANDOM > "old/${d}/${d}.txt"; done
cp -r old new

(upravte některé názvy adresářů a/nebo souborů v new ).

Nyní chceme vytvořit mapu:hash -> název souboru pro každý adresář a poté použít join k porovnání souborů se stejným hashem. Chcete-li vygenerovat mapu, vložte následující do makemap.sh :

find "$1" -type f -exec md5 -r "{}" ; 
  | sed "s/([a-z0-9]*) ${1}/(.*)/1 "2"/" 

makemap.sh vyplivne soubor s řádky formuláře ‚hash „název souboru“‘, takže se připojíme k prvnímu sloupci:

join <(./makemap.sh 'old') <(./makemap.sh 'new') >moves.txt

Tím se vygeneruje moves.txt který vypadá takto:

49787681dd7fcc685372784915855431 "a/a.txt" "bar/a.txt"
bfdaa3e91029d31610739d552ede0c26 "c c/c c.txt" "c c/c c.txt"

Dalším krokem by bylo skutečně provést pohyby, ale mé pokusy uvízly na citaci... mv -i a mkdir -p by se mělo hodit.

Související:jak globovat každý skrytý soubor kromě aktuálního a nadřazeného adresáře?
Linux
  1. [Linux]:Jak kopírovat soubory/adresáře bez přepsání souborů, které jsou již zkopírovány!

  2. Jak změnit příponu více souborů?

  3. Jaký je nejlepší způsob, jak spočítat počet souborů v adresáři?

  1. Rychlý způsob, jak zahrnout cestu k adresáři při volání Mv?

  2. Nejrychlejší způsob, jak extrahovat Iso?

  3. Jak říct Logrotate, aby ignoroval otevřené soubory?

  1. Existuje způsob, jak přimět mv, aby vytvořil adresář, do kterého se má přesunout, pokud neexistuje?

  2. Jak mohu tarovat adresář bez zachování adresářové struktury?

  3. Linux:Porovnejte strukturu adresářů bez porovnávání souborů