rsyncを使用して.mp3ファイルを含むディレクトリのみをコピーする

rsyncを使用して.mp3ファイルを含むディレクトリのみをコピーする

.mp3ファイルを含むフォルダのみを別のデバイスにコピーしようとしています。そして.mp3のみ。構造は次のとおりです。

Band/Year - Album/*.flac
Band/Year - Album/*.txt
Band/Year - Album/*.mp3
Band/Year - Album/covers
Band/Year - Album/covers/*.jpg

多くのマニュアルやフォーラムを読んでいますが、問題を解決することはできません。私が何をしても、コピーに入れたいものをどのように定式化しようとしても、それは除外されるので、消えたりする。

--exclude=* --include=*

何もコピーされません。ディレクトリなしで別のディレクトリでテストしました。くそー。

編集:私が試したが役に立たなかったリスト:

rsync -rnv --exclude=** --include=*/ --include=*/*/ --include=*/*/*/ --include=*/*/*.mp3 "./Be'lakor" /media/moorindal/WALKMAN/MUSIC
rsync -rnv --exclude=** --include=*/ --include=*/*/ --include=*/*/*/ --include=**.mp3 "./Be'lakor" /media/moorindal/WALKMAN/MUSIC
rsync -rnv --exclude=** --include=*/ --include=*/* --include=**.mp3 "./Be'lakor" /media/moorindal/WALKMAN/MUSIC
rsync -rnv --exclude=*/*/* --include=**.mp3 "./Be'lakor" /media/moorindal/WALKMAN/MUSIC
rsync -rnv --exclude=*/*/*.* --include=**.mp3 "./Be'lakor" /media/moorindal/WALKMAN/MUSIC
rsync -rnv --exclude='*/*/*.*' --include='*/*/*.mp3' "./Be'lakor" /media/moorindal/WALKMAN/MUSIC

答え1

まず、--exclude=* --include=*機能しない理由:最初の一致ルールが適用されるためです。*すべてと一致するため、すべてが除外され、rsyncはどのファイルでも2番目のルールを試みません。バラよりRsyncフィルタ:1つのパターンのみをコピーrsync フィルタのガイドです。

.mp3必要なファイルを含めるには

rsync -a -m --include='*.mp3' --include='*/' --exclude='*'

つまり、MP3を含み、すべてのディレクトリを含み(ディレクトリが含まれていない場合はディレクトリにファイルは含まれません)、他のすべてのエントリを除外します。この-mオプション(別名--prune-empty-dirs)を使用すると、rsyncはコピーするファイルが含まれていないディレクトリをスキップします。ただし、.mp3このファイルと同じディレクトリにある他のファイルは含まれません。これを行うには、シェルや他のツールの助けが必要です。

zshでは、.mp3サブディレクトリのファイルを一致させて**/*.mp3から使用できます。履歴修飾子としてグローバル予選結果を.mp3ファイルを含むディレクトリのリストに変換します。

rsync -a **/*.mp3(:h) /destination

ディレクトリが多すぎる場合(またはより正確には、名前を合わせた長さが大きすぎる場合)、コマンドラインの制限が壊れる可能性があります。重複したアイテムを削除すると役に立ちます。

typeset -aU directories
directories=(**/*.mp3(:h))
rsync -a $directories /destination

これは、コマンドが長すぎるリスクを排除するのではなく、コマンドの長さを短くするだけです。リスクを排除するには、次のようにします。zargsrsync を一括実行します。

autoload -U zargs
typeset -aU directories
directories=(**/*.mp3(:h))
do_rsync () { rsync -a $@ /destination; }
zargs --max-chars=$(($(get_conf ARG_MAX) - 500)) -- $directories -- do_rsync

答え2

rsyncであまりにもたくさんやりたいです。最初にすることは、すべてのMP3ファイルのリストを生成することです。

find Music -type f -iname '*.mp3'

その後、ファイルのリストはファイルを含むディレクトリのリストに変換されます。

sed 's:/[^/]*$::'

リストから重複したディレクトリを削除します。

sort -u

これで必要なディレクトリのリストが作成されました。一度に 1 つずつ rsync にフィードします。ターゲットディレクトリツリーをそのまま残すには、--relativeを使用します。

while IFS= read -r dir; do rsync --archive --relative "$dir" /mnt; done

全体としてパイプラインで:

find Music -type f -iname '*.mp3' |
   sed 's:/[^/]*$::' |
   sort -u |
   while IFS= read -r dir; do rsync --archive --relative "$dir" /mnt; done

答え3

--includeこのような状況を心配したり焦ったりする必要はありません--exclude。よく構造化され、既知の場所にあるファイルをrsyncコピーするように指示します。mp3

cd /path/to/source
rsync -avR */*/*.mp3 /path/to/target/

おそらく、あなたはmp3よく構造化されたレイアウトを想定してこの小さなループを使用してコピーすることができます。

for mp3 in */*/*.mp3
do
    rsync --exclude covers -avR "${mp3%/*}"/ /path/to/target/
done

関連情報