上下文

上下文

上下文

假设我们有以下目录组织

mkdir -p a/foo a/bar b
touch a/1.txt a/2.txt a/foo/b.txt a/bar/b.txt
touch b/b.txt
tree --noreport
.
├── a
│   ├── 1.txt
│   ├── 2.txt
│   ├── bar
│   │   └── b.txt
│   └── foo
│       └── b.txt
└── b
    └── b.txt

并且我们想使用标志将目录a(源)中的所有文件传输到目录(目标) ,但不想删除该文件。b--deleteb/b.txt

有人可能会认为以下命令可以实现这一点。但是,请注意该文件b/b.txt已被删除。

rsync -r --delete a/ b
.
├── a
│   ├── 1.txt
│   ├── 2.txt
│   ├── bar
│   │   └── b.txt
│   └── foo
│       └── b.txt
└── b
    ├── 1.txt
    ├── 2.txt
    ├── bar
    │   └── b.txt
    └── foo
        └── b.txt

使用该标志的原因是因为我希望在目标目录中--delete拥有源目录的精确副本,但我们称其为非“精确”,因为我希望文件不被该标志删除。ab./b/b.txt--delete

我尝试过的方法

使用--exclude标志

显然,我们可以通过使用--exclude标志来达到这种效果。

rsync -r --delete --exclude=b.txt a/ b
.
├── a
│   ├── 1.txt
│   ├── 2.txt
│   ├── bar
│   │   └── b.txt
│   └── foo
│       └── b.txt
└── b
    ├── 1.txt
    ├── 2.txt
    ├── bar
    ├── b.txt
    └── foo

这样做的问题是,即使文件./b/b.txt没有被删除,文件a/foo/b.txta/bar/b.txt也不会被复制到b

使用--exclude完整路径的标志

rsync -r --delete --exclude=./b/b.txt a/ b
.
├── a
│   ├── 1.txt
│   ├── 2.txt
│   ├── bar
│   │   └── b.txt
│   └── foo
│       └── b.txt
└── b
    ├── 1.txt
    ├── 2.txt
    ├── bar
    │   └── b.txt
    └── foo
        └── b.txt

正如我们上面看到的,执行此操作将删除文件./b/b.txt

使用--filter标志

显然,以下操作可以得到预期的结果。

rsync -r --delete --filter='P b.txt' a/ b
.
├── a
│   ├── 1.txt
│   ├── 2.txt
│   ├── bar
│   │   └── b.txt
│   └── foo
│       └── b.txt
└── b
    ├── 1.txt
    ├── 2.txt
    ├── bar
    │   └── b.txt
    ├── b.txt
    └── foo
        └── b.txt

但是,如果我们删除a/foo/b.txt

rm -f a/foo/b.txt
.
├── a
│   ├── 1.txt
│   ├── 2.txt
│   ├── bar
│   │   └── b.txt
│   └── foo
└── b
    ├── 1.txt
    ├── 2.txt
    ├── bar
    │   └── b.txt
    ├── b.txt
    └── foo
        └── b.txt

如果我们再次执行,该文件将不会从目标目录中删除rsync

rsync -r --delete --filter='P b.txt' a/ b
.
├── a
│   ├── 1.txt
│   ├── 2.txt
│   ├── bar
│   │   └── b.txt
│   └── foo
└── b
    ├── 1.txt
    ├── 2.txt
    ├── bar
    │   └── b.txt
    ├── b.txt
    └── foo
        └── b.txt

答案1

如果您避免使用该--delete标志,则目标上的文件将不会被删除。

rsync -rt a/ b

看到问题的更新,解释了为什么需要使用删除,以下命令将避免更新或删除最顶层b.txt

rsync -rt --delete --exclude '/b.txt' a/ b/

排除文件名上的前导/将其绑定到源/目标路径名的开头,从而阻止它匹配等。(如果您熟悉 RE,bar/b.txt可以将其视为等同于。)^


并非严格意义上的主题,但如果您使用-rt而不是-r那么文件时间也将被复制。这意味着当您重复 时,它rsync可以跳过自上次复制以来未更改的文件。如果您要复制到本机文件系统(即非 NTFS 或 vFAT),则使用-a(甚至-aHXA)而不是-rt并复制更多元数据。

答案2

您可以使用-b(备份) 选项rsync。文件b/b.txt将重命名为,命令完成b/b.txt~后您可以将其重命名为以前的名称。rsync

您还可以使用参数指定要添加到文件名的--suffix另一个后缀(而不是),或使用 参数将文件移动到另一个目录而不是重命名。有关详细信息,请参阅。~--backup-dirman rsync

相关内容