デスクトップからモバイルデバイスに音楽を同期するためのbashスクリプトを作成しようとしています。デスクトップがソースです。
Rsyncにファイルを再帰的に同期させ、ディレクトリ構造を無視する方法はありますか?デスクトップからファイルが削除された場合は、デバイスでも削除してほしい。
デスクトップのディレクトリ構造はこんな感じです。
Artist1/
Artist1/art1_track1.mp3
Artist1/art1_track2.mp3
Artist1/art1_track3.mp3
Artist2/
Artist2/art2_track1.mp3
Artist2/art2_track2.mp3
Artist2/art2_track3.mp3
...
デバイスに必要なディレクトリ構造は次のとおりです。
Music/
art1_track1.mp3
art1_track2.mp3
art1_track3.mp3
art2_track1.mp3
art2_track2.mp3
art2_track3.mp3
...
単に:
rsync -a --delete --include=*.mp3 --exclude=* \
pathToSongs/Theme*/Artist*/. destuser@desthost:Music/.
パス階層のレベル数が固定されている場合は、この作業を実行します。
警告:2つの曲ファイルの名前がまったく同じで、同じ宛先ディレクトリにある場合、バックアップではそのうちの1つが失われます。
そうでなければ、そしてあなたの質問に厳密に答えるためにディレクトリ構造を無視してあなたは bash のshopt -s globstar
機能を使うことができます:
shopt -s globstar
rsync -a --delete --include=*.mp3 --exclude=* \
pathToSongsRoot/**/. destuser@desthost:Music/.
find
コマンドにフォークする必要はまったくありません。
質問に厳密に答えるために、拡張機能に限定されてはなりません。
shopt -s globstar
rsync -d --delete sourceRoot/**/. destuser@desthost:destRoot/.
これにより、ディレクトリもコピーされますが、コンテンツは含まれません。すべてのファイルおよびディレクトリは、destRoot/
の同じレベルに保存されます。
警告:同じ名前のいくつかの異なるファイルがdefferentsディレクトリに存在する場合、それらは宛先で単に上書きされ、rsync中に、最終的に1つだけをランダムに保存します。
これは最近のオプションかもしれませんが、--no-relative
のドキュメントに記載されているオプション--files-from
が表示され、うまく機能しました。
find SourceDir -name \*.mp3 | rsync -av --files-from - --no-relative . DestinationDir/
あなたの質問への答え:いいえ、rsync
はこれを単独で行うことはできません。しかし、他のツールの助けを借りて、そこにたどり着くことができます...数回の試行の後、私はこれを思いつきました:
rsync -d --delete $(find . -type d|while read d ; do echo $d/ ; done) /targetDirectory && rmdir /targetDirectory/* 2>&-
難しさはこれです:ターゲット位置でファイルの削除を有効にするには、次のことを行う必要があります。
rsync
は、ターゲットでのみ最後のディレクトリの内容を提供します)。したがって、コマンド置換($(
)
で囲まれたもの)はこれを行います。すべてのディレクトリを検索し、ディレクトリ名の最後にスラッシュ(/)を追加します。これで、rsyncはソースディレクトリのリストを確認します。これらはすべてスラッシュで終了しているため、その内容をターゲットディレクトリにコピーします。オプション-d
は、再帰的にコピーしないように指示します。
2番目のトリックはrmdir /targetDirectory/*
で、rsync
が作成した空のディレクトリを削除します(ただし、そうするように依頼していません)。
ここでテストしたところ、ソースツリーで削除されたファイルの削除は問題なく機能しました。
ファイルのリストを作成できれば、すでに問題は解決しています。試してみてください:
find /path/to/src/ -name \*.mp3 > list.txt
rsync -avi --no-relative --progress --files-from=list.txt / user@server:/path/to/dest
新しいファイルに対してスクリプトを再度実行すると、不足しているファイルのみがコピーされます。
リストが気に入らない場合は、1つの文を試してください(ただし、これは別のロジックです)
find /path/to/src/ -name \*.mp3 -type f \
-exec rsync -avi --progress {} user@server:/path/to/dest/ \;
この場合、文の種類によっては以前にファイルリストを作成できないため、毎回各ファイルを要求します。