【问题标题】:Using Rsync include and exclude options to include directory and file by pattern使用 Rsync 包含和排除选项按模式包含目录和文件
【发布时间】:2012-04-14 16:06:48
【问题描述】:

我在正确使用rsync 语法时遇到问题,我想知道我的场景是否真的可以用rsync 处理。首先,我已经确认rsync 在我的本地主机和远程主机之间工作得很好。对目录进行直接同步是成功的。

这是我的文件系统的样子:

uploads/
  1260000000/
    file_11_00.jpg
    file_11_01.jpg
    file_12_00.jpg
  1270000000/
    file_11_00.jpg
    file_11_01.jpg
    file_12_00.jpg
  1280000000/
    file_11_00.jpg
    file_11_01.jpg
    file_12_00.jpg

我想要做的是仅对子目录中以“file_11_”开头的文件运行 rsync,并且我希望能够只运行一个 rsync 作业来同步子目录中的所有这些文件。

这是我正在尝试的命令:

rsync -nrv --include="**/file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/

这导致0 文件在我的试运行中被标记为传输。我尝试了 --include--exclude 语句的各种其他组合,但要么继续没有结果,要么得到了一切,就好像没有设置包含或排除选项一样。

有人知道怎么做吗?

【问题讨论】:

    标签: linux unix rsync darwin


    【解决方案1】:

    问题是--exclude="*" 说要排除(例如)1260000000/ 目录,因此rsync 永远不会检查该目录的内容,因此永远不会注意到该目录包含您的匹配的文件--include.

    我认为最接近你想要的是:

    rsync -nrv --include="*/" --include="file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/
    

    (这将包括所有目录,以及与file_11*.jpg 匹配的所有文件,但不包括其他文件),或者可能这个:

    rsync -nrv --include="/[0-9][0-9][0-9]0000000/" --include="file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/
    

    (相同的概念,但对包含的目录更加挑剔)。

    【讨论】:

    • 谢谢!这正是我所需要的。我的场景实际上或多或少是您在第二个示例中描述的,但我简化了我的问题以使问题更直接。
    • 请注意(例如)--include="*/" 在包含您实际要包含的文件的 目录中的重要性。
    • 注意参数的顺序:--include必须在--exclude之前
    • @hfs 是的,我觉得这个应该在实际答案中提到。在找到此页面之前,我试图做类似的事情,并且知道我需要-include="*/",但它仍然不起作用。看着这个答案,我的第一个想法是“这正是我正在做的事情!”。然后我注意到顺序不同了。
    • 另一个关键概念是“当使用 --recursive (-r) 选项(由 -a 隐含)时,每个路径的每个子组件都是自上而下访问的,因此包含/排除模式递归地应用于每个子组件的全名"
    【解决方案2】:

    rsync 包括排除模式示例:

    "*"         means everything
    "dir1"      transfers empty directory [dir1]
    "dir*"      transfers empty directories like: "dir1", "dir2", "dir3", etc...
    "file*"     transfers files whose names start with [file]
    "dir**"     transfers every path that starts with [dir] like "dir1/file.txt", "dir2/bar/ffaa.html", etc...
    "dir***"    same as above
    "dir1/*"    does nothing
    "dir1/**"   does nothing
    "dir1/***"  transfers [dir1] directory and all its contents like "dir1/file.txt", "dir1/fooo.sh", "dir1/fold/baar.py", etc...
    

    最后要注意的是,不要依赖一开始用于评估路径的星号;像 "**dir" (可以将它们用于单个文件夹或文件,但不能用于路径)并注意两个以上的星号不适用于文件名。

    【讨论】:

    • 您的答案是唯一可用的,因为您解释了一般行为。根据 OP,其他答案过于具体,但每种情况都需要另一种解决方案!这对我帮助很大!
    • @AlBundy 我很高兴!
    • 可以在rsync 手册页的INCLUDE/EXCLUDE PATTERN RULES 部分中找到详尽但不那么直观的解释
    【解决方案3】:

    在上面推荐的答案中添加 -m 以修剪空目录。

    【讨论】:

      【解决方案4】:

      这是我“教人钓鱼”的答案:

      Rsync 的语法绝对不直观,但值得理解。

      1. 首先,使用-vvv 查看rsync 的调试信息。
      $ rsync -nr -vvv --include="**/file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/
      
      [sender] hiding directory 1280000000 because of pattern *
      [sender] hiding directory 1260000000 because of pattern *
      [sender] hiding directory 1270000000 because of pattern *
      

      这里的关键概念是 rsync 递归地为每个目录应用包含/排除模式。一旦第一个包含/排除匹配,处理就会停止。

      它评估的第一个目录是/Storage/uploadsStorage/uploads1280000000/, 1260000000/, 1270000000/ 目录/文件。它们都不匹配 file_11*.jpg 以包含。所有这些都匹配* 以排除。因此它们被排除在外,rsync 结束。

      1. 解决方案是首先包含所有目录 (*/)。那么第一个 dir 组件将是 1260000000/, 1270000000/, 1280000000/,因为它们匹配 */。下一个目录组件将是1260000000/。在1260000000/ 中,file_11_00.jpg 匹配--include="file_11*.jpg",因此包含在内。等等。
      $ rsync -nrv --include='*/' --include="file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/
      
      ./
      1260000000/
      1260000000/file_11_00.jpg
      1260000000/file_11_01.jpg
      1270000000/
      1270000000/file_11_00.jpg
      1270000000/file_11_01.jpg
      1280000000/
      1280000000/file_11_00.jpg
      1280000000/file_11_01.jpg
      

      https://download.samba.org/pub/rsync/rsync.1

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-02
        • 2022-09-26
        • 2018-08-29
        • 2020-03-22
        • 1970-01-01
        • 2021-06-25
        • 1970-01-01
        相关资源
        最近更新 更多