21

我正在尝试创建一个 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
    ...
4

4 回答 4

19

简单地:

rsync -a --delete --include=*.mp3 --exclude=* \
    pathToSongs/Theme*/Artist*/. destuser@desthost:Music/.

如果您的路径层次结构具有固定数量的级别,则可以完成这项工作。

警告:如果两个歌曲文件的名称完全相同,而在同一目标目录中,您的备份将丢失其中一个!

如果是这样,并且为了严格回答您的问题而忽略目录结构,您可以使用shopt -s globstar功能:

shopt -s globstar
rsync -a --delete --include=*.mp3 --exclude=* \
    pathToSongsRoot/**/. destuser@desthost:Music/.

根本不需要 fork 来find指挥。

递归同步所有文件,同时忽略目录结构

为了严格回答问题,不得仅限于扩展:

shopt -s globstar
rsync -d --delete sourceRoot/**/. destuser@desthost:destRoot/.

这样,目录也将被复制,但没有内容。所有文件目录都将存储在同一级别destRoot/

警告:如果在不同的目录中存在一些具有相同名称的不同文件,它们将在 rsync 期间被简单地覆盖在目标上,最终只随机存储一个。

于 2013-02-02T14:47:24.210 回答
14

可能这是一个最近的选项,但我看到--no-relative文档中提到的选项--files-from并且效果很好。

find SourceDir -name \*.mp3 | rsync -av --files-from - --no-relative . DestinationDir/
于 2017-01-27T15:36:16.697 回答
1

您的问题的答案:不,rsync不能单独做到这一点。但是在其他工具的帮助下,我们可以到达那里......经过几次尝试,我想出了这个:

rsync -d --delete $(find . -type d|while read d ; do echo $d/ ; done) /targetDirectory && rmdir /targetDirectory/* 2>&-

困难在于:要启用删除目标位置的文件,您需要:

  1. 指定目录作为 rsync 的源(如果源是文件列表,它不会删除)。
  2. 一次给它完整的源列表(rsync在循环内只会给你最后一个目录的内容在目标)。
  3. 用斜杠结束目录名称(否则它会在目标目录中创建目录)

所以命令替换(用 . 括起来的东西$( ))是这样做的:它找到所有目录并在目录名称的末尾添加一个斜杠 (/)。现在 rsync 看到一个源目录列表,所有目录都以斜线结尾,因此将它们的内容复制到目标目录。该选项-d告诉它,不要递归复制。

第二个技巧是rmdir /targetDirectory/*删除创建的空目录rsync(尽管我们没有要求它这样做)。

我在这里进行了测试,删除源树中删除的文件效果很好。

于 2013-02-02T16:08:31.070 回答
1

如果您可以列出文件,那么您已经解决了问题。尝试:

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/  \;

在这种情况下,您将每次都询问每个文件,因为根据句子的类型,您以前无法构建文件列表。

于 2018-01-24T18:26:55.007 回答