rsync:从排除的目录中包含文件

4

所以,我目前正在编写自己的简单备份客户端(显然基于rsync),经过大量的试错后,我只剩下了(希望)一个问题。

源文件夹结构

.
├── .hidden_file.txt
├── .hidden_folder
│   └── .keep
├── regular_file.txt
└── regular_folder
    └── .keep

备份命令

您可以看到,我试图“简单地”排除与regular*匹配的所有内容,但明确包括regular_folder文件夹中的.keep文件。 这至少是个想法。

rsync --archive --relative --prune-empty-dirs <many other options> \
      --include='/data/source/regular_folder/.keep' \
      --exclude='regular*' \
      /data/source /data/target/<timestamp>

我需要的是什么

.
├── .hidden_file.txt
└── .hidden_folder
    └── .keep
└── regular_folder
    └── .keep

实际获得的内容

.
├── .hidden_file.txt
└── .hidden_folder
    └── .keep

我显然做了我的公平份额的googeling和man-page阅读,但是可能有些明显的东西已经溜走了,或者...我不知道。

我理解,在我的情况下,我还必须--include='/data/source/regular_folder/(我想要的文件的父目录)但是如果其他文件与.keep并排存在,它们将自动包括在内,这是我不想要的

感谢您的帮助,我非常感激:)

更新

编辑 忽略所有这些。根据我的新测试用例,它不再起作用了(这是有道理的,因为排除应该始终优先于源。不知道为什么它在我的最初测试中起作用)。回到绘图板:/

原版 在按照ams提出的方法进行单元测试后(遗憾的是没有达到我想要的效果),我想到了别的办法。

我可以通过将我明确想要的文件/文件夹添加为rsync的附加,而不是通过--include来添加它们。 新命令看起来像这样:

rsync --archive --relative --prune-empty-dirs <many other options> \
      --exclude='regular*' \
      /data/source /data/source/regular_folder/.keep' \
      /data/target/<timestamp>

这很好用,但是……你猜对了,还有另一个问题。当源文件需要进入目录时,通配符实际上并不起作用。比如我想保留所有的.keep 文件,我希望可以这样做:
rsync --archive --relative --prune-empty-dirs <many other options> \
      --exclude='regular*' \
      /data/source /data/source/*/.keep' \
      /data/target/<timestamp>

多个*也不起作用。

现在的问题是,我只是太蠢了无法让它工作,还是这是不可能的?

我知道源文件可以在扁平层次结构中使用通配符。例如,以下内容将作为源文件起作用:

/some/path/*.txt

你考虑过发出两个命令,其中第二个命令只是为了.keep文件吗? - Rolf of Saxony
是的,我考虑过这个,但不太喜欢它,因为rsync可以处理包含/排除。所以必须有一种方法只使用一个命令来使其工作 :) - tadly
祝你好运,我相信一定会有答案的。需要记住的一件事是,在未来你的需求会发生变化,当它们改变时,再次弯曲你的自定义命令将会变得复杂。有时候简单就是最好的选择。 - Rolf of Saxony
1个回答

4

试试这个:

--include='/data/source/regular_folder/.keep'
--exclude='regular*/**'

基本上,这将排除regular_folder内的所有文件,但不包括该文件夹本身。

它确实会排除子目录,因此更深层次的.keep文件将无法起作用。如果您有这样的情况,那么以下内容应该可以解决:

--include='/data/source/regular_folder/.keep'
--include='/data/source/regular_folder/deeper/deeper/.keep'
--include='*/'
--exclude='regular*/**'

或者,简单地包含所有.keep文件:

--include='.keep'
--include='*/'
--exclude='regular*/**'
< p > < code >“*/”< /code >表示“包括所有目录”,但并不涉及文件。< /p >

非常感谢。 明天会尝试并报告结果 :) 如果成功了,只需要正确配置客户端UI中的路径/模式(到那时将需要适当的文档 叹气 :D)。 - tadly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接