我正在尝试创建一个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
...
答案 0 :(得分:13)
简单地:
rsync -a --delete --include=*.mp3 --exclude=* \
pathToSongs/Theme*/Artist*/. destuser@desthost:Music/.
如果您的路径层次结构具有固定数量的级别,将完成此任务。
警告:如果两个歌曲文件的名称完全相同,则在同一目标目录中,您的备份将错过其中一个!
如果没有其他问题,并严格按照忽略目录结构进行回答,您可以使用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 :(得分:7)
可能这是最近的选项,但我看到--no-relative
文档中提到的选项--files-from
,效果很好。
find SourceDir -name \*.mp3 | rsync -av --files-from - --no-relative . DestinationDir/
答案 2 :(得分:1)
你的问题的答案:不,rsync
不能单独做到这一点。但是在其他工具的帮助下,我们可以到达那里......经过几次尝试,我想出了这个:
rsync -d --delete $(find . -type d|while read d ; do echo $d/ ; done) /targetDirectory && rmdir /targetDirectory/* 2>&-
难点在于:要在目标位置删除文件,您需要:
rsync
将仅为目标提供最后一个目录的内容。)因此命令替换($(
)
附带的内容)执行此操作:它找到所有目录并在目录名称的末尾添加斜杠(/)。现在,rsync会看到一个源目录列表,所有源目录都以斜杠结束,因此将其内容复制到目标目录。选项-d
告诉它,不要递归复制。
第二个技巧是rmdir /targetDirectory/*
删除rsync
创建的空目录(虽然我们没有要求它这样做)。
我在这里测试过,删除源树中删除的文件就可以了。
答案 3 :(得分:0)
如果您可以制作文件列表,那么您已经解决了问题。 尝试:
find /path/to/src/ -name \*.mp3 > list.txt
rsync -avi --no-relative --progress --files-from=list.txt / user@server:/path/to/dest
如果再次为新文件运行脚本,它将只复制丢失的文件。
如果您不喜欢该列表,那么请尝试一句话(但它是另一种逻辑)
find /path/to/src/ -name \*.mp3 -type f \
-exec rsync -avi --progress {} user@server:/path/to/dest/ \;
在这种情况下,您将每次询问每个文件,因为根据句子类型,您无法先构建文件列表。