我必须将一些文件/目录从几个人共享的目录移动到另一台计算机。我必须移动的元素是一些目录、一些子目录、子目录中的一些特定文件等……有点乱 ^^
我正在尝试应用https://serverfault.com/a/788007/154366中的方法,但不知何故失败了。
这是我的测试设置(我试图使其具有足够的代表性,以便能够理解其中的大部分复杂之处,rsync --filter=merge
以便我可以将它应用到我的实际问题中):
#!/bin/bash
mkdir -p /tmp/test/{a/b,b/{a,b},c,.d}
touch /tmp/test/{f.txt,.f.txt,{a/b,b,b/{a,b},c,.d}/f.txt,b/.f.txt}
tree -a /tmp/test
/tmp/test
├── a
│ └── b
│ └── f.txt
├── b
│ ├── a
│ │ └── f.txt
│ ├── b
│ │ └── f.txt
│ ├── .f.txt
│ └── f.txt
├── c
│ └── f.txt
├── .d
│ └── f.txt
├── .f.txt
└── f.txt
现在我想使用单个rsync -av
命令将以下项目从 复制/tmp/test
到/tmp/filt
:
- 完整
./a
目录 - 完整
./b/b
目录 ./b
目录的所有文件和点文件直接子目录./
目录的所有文件(非点文件)的直接子目录
我预期的“副本”在此处标记=>
:
/tmp/test/ => /tmp/filt/
/tmp/test/a/ => /tmp/filt/a/
/tmp/test/a/b/ => /tmp/filt/a/b/
/tmp/test/a/b/f.txt => /tmp/filt/a/b/f.txt
/tmp/test/b/ => /tmp/filt/b/
/tmp/test/b/a/
/tmp/test/b/a/f.txt
/tmp/test/b/b/ => /tmp/filt/b/b/
/tmp/test/b/b/f.txt => /tmp/filt/b/b/f.txt
/tmp/test/b/f.txt => /tmp/filt/b/f.txt
/tmp/test/b/.f.txt => /tmp/filt/b/.f.txt
/tmp/test/c/
/tmp/test/c/f.txt
/tmp/test/.d/
/tmp/test/.d/f.txt
/tmp/test/f.txt => /tmp/filt/f.txt
/tmp/test/.f.txt
因此我编写了以下filter.txt
文件以便与 rsync 一起使用它--filter=merge
:
+ /[!.]*
+ /a/
+ /a/**
+ /b/
+ /b/b/
+ /b/b/**
- /b/*/
+ /b/*
- /**
但是当我运行命令时:
rsync -av --dry-run --filter='merge filter.txt' /tmp/test /tmp/filt/
我得到:
sending incremental file list
test/
sent 74 bytes received 20 bytes 188.00 bytes/sec
total size is 0 speedup is 0.00 (DRY RUN)
注意:当然,该/tmp/filt
目录不存在,因此缺少输出与它无关。
我做错什么了?
您需要注意源目录是否以 结尾的区别
/
。您引用的示例答案有一个结尾斜杠。如果您执行相同的操作,它应该可以工作:过滤模式不起作用,因为它们与类似 的文件进行
test/a/
比较/a/
。为了避免复制目录
c
,您可以删除过滤规则的第一行和最后一行,并添加,例如,在最后 3 条规则以排除顶级点文件和目录,但包括其他文件。和
+ /b/b/
可以+ /b/b/**
折叠成+ /b/b/***
。