上下文
假设我们有以下目录组织
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
--delete
b/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
拥有源目录的精确副本,但我们称其为非“精确”,因为我希望文件不被该标志删除。a
b
./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.txt
和a/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-dir
man rsync