AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 449284
Accepted
Calaf
Calaf
Asked: 2018-06-13 02:29:01 +0800 CST2018-06-13 02:29:01 +0800 CST 2018-06-13 02:29:01 +0800 CST

递归复制具有给定名称的目录

  • 772

使用构建的目录结构

#!/bin/bash
for name in A B
do
    mkdir -p /tmp/src/${name}/copyme
    echo "do not copy" > /tmp/src/${name}/no.txt
    echo "copy" > /tmp/src/${name}/copyme/yes.txt
done

我只想将copyme目录以及其中的文件镜像到 /tmp/tgt。

这应该很简单。依靠rsync区分命令行选项的顺序:排除一切,然后包含相关模式。然而

rsync -av --exclude='*' --include='copyme' /tmp/src/ /tmp/tgt/

排除所有内容(仅创建目标目录)。为什么?

rsync recursive
  • 1 1 个回答
  • 725 Views

1 个回答

  • Voted
  1. Best Answer
    Kusalananda
    2018-06-13T03:33:27+08:002018-06-13T03:33:27+08:00

    运行时rsync,它会根据模式测试源中找到的名称,并且第一个匹配模式生效:

    $ rsync -avv --exclude='*' --include='copyme' /tmp/src/ /tmp/tgt/
    sending incremental file list
    [sender] hiding directory A because of pattern *
    [sender] hiding directory B because of pattern *
    delta-transmission disabled for local transfer or --whole-file
    total: matches=0  hash_hits=0  false_alarms=0 data=0
    
    sent 51 bytes  received 86 bytes  274.00 bytes/sec
    total size is 0  speedup is 0.00
    

    当一个目录被排除时(参见上面的“隐藏目录...”),它的内容不会被进一步考虑。颠倒排除和包含模式将无济于事,因为它永远不会到达copyme目录。

    rsync手册说:

    例如,要包含/foo/bar/baz、目录/foo,并且 /foo/bar不能被排除。排除其中一个父目录会阻止对其内容的检查,切断 rsync对这些路径的递归,并使包含 /foo/bar/baz无效(因为rsync无法匹配它在目录层次结构的切断部分中从未见过的东西)。

    所以与其:

    $ rsync -avv --include='[AB]' --include='copyme/***' --exclude='*' /tmp/src/ /tmp/tgt/
    sending incremental file list
    [sender] showing directory A because of pattern [AB]
    [sender] showing directory B because of pattern [AB]
    [sender] showing directory A/copyme because of pattern copyme/***
    [sender] hiding file A/no.txt because of pattern *
    [sender] showing file A/copyme/yes.txt because of pattern copyme/***
    [sender] showing directory B/copyme because of pattern copyme/***
    [sender] hiding file B/no.txt because of pattern *
    [sender] showing file B/copyme/yes.txt because of pattern copyme/***
    created directory /tmp/tgt
    delta-transmission disabled for local transfer or --whole-file
    ./
    A/
    A/copyme/
    A/copyme/yes.txt
    B/
    B/copyme/
    B/copyme/yes.txt
    total: matches=0  hash_hits=0  false_alarms=0 data=10
    
    sent 305 bytes  received 175 bytes  960.00 bytes/sec
    total size is 10  speedup is 0.02
    

    请注意,排除必须排在最后,在包含之后。该copyme/***模式匹配copyme目录名本身和它下面的任何路径名。

    如果您不想硬编码A和B目录名称:

    for dir in /tmp/src/*; do
        [ ! -d "$dir" ] && continue
        rsync -avv --include="${dir##*/}" --include='copyme/***' --exclude='*' /tmp/src/ /tmp/tgt/
    done
    

    这将输出

    sending incremental file list
    [sender] showing directory A because of pattern A
    [sender] hiding directory B because of pattern *
    [sender] showing directory A/copyme because of pattern copyme/***
    [sender] hiding file A/no.txt because of pattern *
    [sender] showing file A/copyme/yes.txt because of pattern copyme/***
    created directory /tmp/tgt
    delta-transmission disabled for local transfer or --whole-file
    ./
    A/
    A/copyme/
    A/copyme/yes.txt
    total: matches=0  hash_hits=0  false_alarms=0 data=5
    
    sent 180 bytes  received 148 bytes  656.00 bytes/sec
    total size is 5  speedup is 0.02
    sending incremental file list
    [sender] hiding directory A because of pattern *
    [sender] showing directory B because of pattern B
    [sender] showing directory B/copyme because of pattern copyme/***
    [sender] hiding file B/no.txt because of pattern *
    [sender] showing file B/copyme/yes.txt because of pattern copyme/***
    delta-transmission disabled for local transfer or --whole-file
    B/
    B/copyme/
    B/copyme/yes.txt
    total: matches=0  hash_hits=0  false_alarms=0 data=5
    
    sent 180 bytes  received 117 bytes  594.00 bytes/sec
    total size is 5  speedup is 0.02
    

    结果将是

    $ tree src tgt
    src
    |-- A
    |   |-- copyme
    |   |   `-- yes.txt
    |   `-- no.txt
    `-- B
        |-- copyme
        |   `-- yes.txt
        `-- no.txt
    
    4 directories, 4 files
    tgt
    |-- A
    |   `-- copyme
    |       `-- yes.txt
    `-- B
        `-- copyme
            `-- yes.txt
    
    4 directories, 2 files
    

    另一种不使用排除或包含模式rsync但用于find定位copyme目录然后rsync复制它们的方法:

    find /tmp/src -type d -name 'copyme' -prune -exec sh -c '
        cd /tmp/src && rsync -aRvv "${1#/tmp/src/}/" /tmp/tgt/' sh {} ';'
    

    注意这里使用的-R( --relative) 标志rsync。

    sh -c为每个找到copyme的目录执行的脚本执行一个cdto /tmp/src,然后复制路径名,并/tmp/src删除其路径的初始位。

    -pruneinfind命令停止在找到的目录中find查找更多copyme目录。

    • 0

相关问题

  • tar 目录只发送修改过的文件块

  • 如何复制具有相对重复符号链接的目录树?

  • cp 在 . (dot) 或 .. (dot dot) 是源目录

  • rsync 排除问题

  • rsync 端口 22 和 873 使用

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve