我在远程服务器上有一个类似的目录结构,列出了以下一些文件:
/logs/service::A1/20210730T120000/log.log
/logs/service::A1/20210729T120000/log.log
/logs/service::A2/20210730T120000/log.log
/logs/service::B0/20210730T120000/log.log
为了访问rsync
serviceA 中的所有文件,我只需使用单个通配符运行以下命令*
rsync -av <remote-server>:/logs/service::A* <destination>
这按预期工作,我在目的地得到以下目录结构:
<destination>/service::A1/20210730T120000/log.log
<destination>/service::A1/20210729T120000/log.log
<destination>/service::A2/20210730T120000/log.log
但是,如果我想rsync
serviceA 中的所有文件从某一天开始,我需要第二个通配符,如下所示:
rsync -arv <remote-server>:/logs/service::A*/20210730* <destination>
然而,这样我就失去了顶级目录,并在目的地给出了以下结构:
<destination>/20210730T120000/log.log
<destination>/20210730T120000/log.log
我仍然想要service::<xx>
目的地的水平。似乎实现这一目标的方法是通过旗帜--include/--exclude
。
不过我尝试了以下方法这里但没有找到文件:
rsync -av --include='service::A**/20210730**' --exclude='*' <remote-server>:/logs/ <destination>
receiving incremental file list
./
答案1
/service::A*/20210730*/**
您很可能想要使用包含模式和*/
以及排除模式的组合
*
。您可能还希望包含-m
( --prune-empty-dirs
) 以仅创建保存实际传输的文件所需的目录结构。
rsync -avm \
--include='/service::A*/20210730*/**' \
--include='*/' \
--exclude='*' \
remote:/logs/ local-path/logs
在传输的文件列表阶段,这将遍历以/logs
远程主机为根的整个层次结构,包括每个目录(由于*/
包含模式)以及与第一个模式匹配的所有文件和目录,但排除其他任何内容。然后,在传输实际开始之前,目录和文件的路径名列表将被删除为空目录(“空”意味着“不包含与任何包含模式匹配的文件”)。
*/
需要该模式来允许rsync
输入匹配的目录/service::A*
等,因为否则由于排除模式,这是不可能的*
。
由于上述解决方案需要完整遍历 下的所有内容/logs
,因此如果您有巨大的文件层次结构,这可能会很慢。
如果是这样,您可以通过更有选择性地选择包含模式来加快速度:
rsync -avm \
--include='/service::A*/' \
--include='/service::A*/20210730*/***' \
--exclude='*' \
remote:/logs/ local-path/logs
这明确允许rsync
输入匹配的目录/service::A*/
。然后它包括我们感兴趣的所有带有时间戳的目录,同时排除其他所有内容。
类似的模式与前者dir/***
的不同之处dir/**
在于前者还包括dir
目录本身。