使用 rsync 仅复制包含 .mp3 文件的目录

Yur*_*kov 5 rsync wildcards

我正在尝试仅将其中包含 .mp3 文件的文件夹复制到另一台设备。并且只有其中的 .mp3。结构如下所示:

Band/Year - Album/*.flac
Band/Year - Album/*.txt
Band/Year - Album/*.mp3
Band/Year - Album/covers
Band/Year - Album/covers/*.jpg
Run Code Online (Sandbox Code Playgroud)

我已经阅读了大量的手册和论坛,但无法解决我的问题。无论我做什么,无论我如何试图制定我想在复制中包含的内容,因为它被排除在外 - 它甚至消失了

--exclude=* --include=*
Run Code Online (Sandbox Code Playgroud)

不会复制任何东西。我在另一个目录上测试了它,即使没有,该死的。

编辑:我尝试无济于事的列表:

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
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 6

首先,为什么--exclude=* --include=*不起作用:因为第一个匹配规则适用。*匹配所有内容,因此所有内容都被排除,并且 rsync 甚至不会对任何文件尝试第二条规则。有关rsync 过滤器的指南,请参阅 Rsync 过滤器:仅复制一种模式。

要包含.mp3文件,您需要

rsync -a -m --include='*.mp3' --include='*/' --exclude='*'
Run Code Online (Sandbox Code Playgroud)

即包括 MP3,包括所有目录(如果不包括目录,则不包括其中的任何文件)并排除其他所有内容。该-m选项(又名--prune-empty-dirs)使 rsync 跳过不包含任何要复制的文件的目录。但这不会包含与该文件位于同一目录中的其他文件.mp3。为此,您需要 shell 或其他工具的帮助。

在 zsh 中,您可以使用 来匹配.mp3子目录中的文件**/*.mp3,然后使用历史修饰符作为glob 限定符将结果转换为包含文件的目录列表.mp3

rsync -a **/*.mp3(:h) /destination
Run Code Online (Sandbox Code Playgroud)

如果您有太多目录(或者更准确地说,如果它们名称的组合长度太大),这可能会打破命令行限制。删除重复项可能会有所帮助:

typeset -aU directories
directories=(**/*.mp3(:h))
rsync -a $directories /destination
Run Code Online (Sandbox Code Playgroud)

这并不能消除命令过长的风险,而只是减少了风险。为了消除该风险,请使用zargs批量运行rsync。

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
Run Code Online (Sandbox Code Playgroud)