排除指定文件的递归拷贝

有时候我们有这种需要:递归复制整个目录(包含子目录和文件)同时排除掉指定类型的文件。此时,第一个想到的工具就是cp,但是cp没有排除指定文件的参数选项,所以需要配合find或者grep才能实现此功能。具体的使用方法,请自行搜索。我测试了其中一个方法,发现无法保持目录结构。最后只得放弃cp。

放弃cp不等于没有其他思路。粗略来说,“复制”可以算作“同步”的同义词,所以可以使用同步工具(或命令)来实现上述要求,如rsync。测试如下:

第一步:建立测试所用的目录、文件等。

1
2
3
$mkdir -p ./raw/aaa/bbb ./raw/ccc ./copy
$touch ./raw/aaa/1.r ./raw/aaa/1.txt ./raw/aaa/1.pl
$touch ./raw/aaa/bbb/2.tex ./raw/aaa/bbb/2.pl ./raw/aaa/bbb/2.r


第二步:使用tree.sh来看一下搭建起来的测试环境。

1
2
3
4
5
6
7
8
9
10
11
12
$tree.sh .
|---raw
||---ccc
||---aaa
|||---1.r
|||---1.txt
|||---bbb
||||---2.tex
||||---2.pl
||||---2.r
|||---1.pl
|---copy

第三步:使用rsync同步/复制raw目录下除Perl脚本(*.pl)以外的所有文件至copy目录下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$rsync -vrP --exclude="*.pl" ./raw/ ./copy/
sending incremental file list
aaa/
aaa/1.r
           0 100%    0.00kB/s    0:00:00 (xfer#1, to-check=4/8)
aaa/1.txt
           0 100%    0.00kB/s    0:00:00 (xfer#2, to-check=3/8)
aaa/bbb/
aaa/bbb/2.r
           0 100%    0.00kB/s    0:00:00 (xfer#3, to-check=1/8)
aaa/bbb/2.tex
           0 100%    0.00kB/s    0:00:00 (xfer#4, to-check=0/8)
ccc/
 
sent 292 bytes  received 100 bytes  784.00 bytes/sec
total size is 0  speedup is 0.00

第四步:再次使用tree.sh查看是否完成任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$tree.sh .
|---raw
||---ccc
||---aaa
|||---1.r
|||---1.txt
|||---bbb
||||---2.tex
||||---2.pl
||||---2.r
|||---1.pl
|---copy
||---ccc
||---aaa
|||---1.r
|||---1.txt
|||---bbb
||||---2.tex
||||---2.r

rsync的参数解释:
-v:显示详细信息
-P:显示进度
-r:递归操作
–exclude:设定排除模式
./raw/:源目录
./copy/:目标目录
注意:如果raw后不加/的话,会在目标目录中首先建立一个raw文件夹。copy后加不加/没有什么影响。有兴趣的可以自己测试一下。