同じファイルのドライブが2つありますが、ディレクトリ構造がまったく異なります。
ソース側の構造と一致するように、宛先側のすべてのファイルを「移動」する方法はありますか?おそらくスクリプトで?
たとえば、ドライブAには次のものがあります。
/foo/bar/123.txt
/foo/bar/234.txt
/foo/bar/dir/567.txt
ドライブBには次のものがあります:
/some/other/path/123.txt
/bar/doo2/wow/234.txt
/bar/doo/567.txt
問題のファイルは巨大(800GB)なので、再コピーしたくありません。必要なディレクトリを作成してファイルを移動することで、構造を同期したいだけです。
宛先で各ソースファイルを見つけて、それを一致するディレクトリに移動し、必要に応じて作成する再帰スクリプトを考えていました。しかし—それは私の能力を超えています!
別のエレガントなソリューションがここにあります:
https://superuser.com/questions/237387/any-way-to-sync-directory-structure-when-the-files-are-already-on-both-sides / 238086
承認された回答:
ギレスと一緒に行き、hasenjが提案したユニゾンを紹介します。ユニゾンはDropBoxの20年前にDropBoxでした。多くの人(私自身を含む)が毎日使用する堅実なコード—学ぶ価値があります。それでも、join
それが得ることができるすべての宣伝が必要です🙂
これは答えの半分に過ぎませんが、仕事に戻らなければなりません🙂
基本的に、私はあまり知られていないjoin
をデモンストレーションしたかったのです それを行うユーティリティ:あるフィールドで2つのテーブルを結合します。
まず、スペースを含むファイル名を含むテストケースを設定します。
for d in a b 'c c'; do mkdir -p "old/$d"; echo $RANDOM > "old/${d}/${d}.txt"; done
cp -r old new
(new
でいくつかのディレクトリ名やファイル名を編集します 。
次に、マップを作成します。各ディレクトリのハッシュ->ファイル名を作成してから、join
を使用します。 同じハッシュを持つファイルを照合します。マップを生成するには、makemap.sh
に次のように入力します :
find "$1" -type f -exec md5 -r "{}" ;
| sed "s/([a-z0-9]*) ${1}/(.*)/1 "2"/"
makemap.sh
「hash“ filename”」という形式の行を含むファイルを吐き出すので、最初の列に参加するだけです:
join <(./makemap.sh 'old') <(./makemap.sh 'new') >moves.txt
これにより、moves.txt
が生成されます これは次のようになります:
49787681dd7fcc685372784915855431 "a/a.txt" "bar/a.txt"
bfdaa3e91029d31610739d552ede0c26 "c c/c c.txt" "c c/c c.txt"
次のステップは実際に移動を行うことですが、私の試みは引用に行き詰まりました…mv -i
およびmkdir -p
便利になるはずです。