通过 ssh 进行 rsync,并在 bash 中使用多个通配符,同时保持目录结构

通过 ssh 进行 rsync,并在 bash 中使用多个通配符,同时保持目录结构

我在远程服务器上有一个类似的目录结构,列出了以下一些文件:

/logs/service::A1/20210730T120000/log.log
/logs/service::A1/20210729T120000/log.log
/logs/service::A2/20210730T120000/log.log
/logs/service::B0/20210730T120000/log.log

为了访问rsyncserviceA 中的所有文件,我只需使用单个通配符运行以下命令*

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

但是,如果我想rsyncserviceA 中的所有文件从某一天开始,我需要第二个通配符,如下所示: 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目录本身。

相关内容