语法
cp [OPTION]... SOURCE... DIRECTORY
cp [OPTION]... -t DIRECTORY SOURCE...
这两个语法的效果是一样的,都是把 SOURCE 代表的文件复制到 DIRECTORY 目录中。
Unix 传统中,文件包括普通文件,目录,符号链接,等等。
文件复制到目录
首先来看下如何把文件复制到目录中,使用上面的两种语法
cp file1 file2 file3 dir1
cp -t dir1 file1 file2 file3
注意,目录 dir1 必须存在,否则会发生文件复制重命名。
另外,如果 dir1 目录下存在 file1 ,那么默认将会发生覆盖而不提示用户,这个文章后面将会给出解决办法。
目录复制到目录
有时候,我们想把整个目录复制到另外一个目录下,这个时候,我们需要加上 -r 或 -R 或 --recursive 选项
cp -r dir1/ dir2/
注意,目录 dir2 必须存在,否则会发生目录复制重命令。
目录项复制到目录
cp -r dir1 dir2
是把整个 dir1 目录复制到目录 dir2 下,但是有时候我们只想把 dir1 目录下的内容复制到 dir2 目录下,那该怎么办呢?使用通配符来完成这个任务
cp dir1/* dir2
如果 dir1 目录有 hello.txt 以及 world.txt 两个文件,那么 dir1/*
会被 shell 展开为 dir1/hello.txt
以及 dir1/world.txt
,那么上面的命令的展开形式如下
cp dir1/hello.txt dir2/world.txt dir2
这个形式就是文件复制到目录的操作。
注意,目录 dir2 必须存在,否则会报错。
文件复制重命名
有时候,我们想复制一个文件,但是同时又想把副本(复制后的文件)进行重命名,cp 命令可以做到,只要重命名的名子不存在即可
cp file1 dir1/renamed_file1
这个命名会把当前目录下的 file1 复制到 dir1 目录下,并且重命名为 renamed_file1。
注意,只有在 renamed_file1 不存在的情况下,才会发生文件复制重命名的操作。如果 renamed_file1 存在,那么将会用 file1 的内容覆盖 renamed_file1 的内容。
目录复制重命名
目录复制重命名与文件复制重命名类似,只是复制目录需要加上选项 -r
。
cp -r dir1/ dir2/renamed_dir1
注意,如果想目录复制重命名,那么 renamed_dir1 目录必须不存在。如果存在,那么将会发生把一个目录复制到另外一个目录下的操作。
文件覆盖
在前面的部分中提到一个问题,文件复制可以导致覆盖操作,例如
cp file1 file2 dir1
如果 dir1 目录下存在 file1 文件,那么默认将会发生覆盖,但是不会给我们提示。如果这不是你想要的,那么可以使用下面几个选项
- 使用
-n
选项,不会发生覆盖操作。 - 使用
-i
选项,可以提示操作者是否执行覆盖操作。 - 使用
-b
选项,在覆盖前进行备份,备份文件名是原始文件名加上一个波浪线。 - 使用
-u
选项,表示只有文件比较新的时候,才发生覆盖。
备份文件
文章最后部分,再介绍一个内容,备份文件。
刚才说过使用 -b
选项,可以在文件发生覆盖的时候,对文件进行备份,备份文件名是原始文件名加一个波浪线后缀,但是我们可以通过--suffix
重新定义备份文件名后缀。
cp --suffix=.bak file1 dir1
注意,如果指定了 --suffix
选项,那么已经包含了 -b
的意思,因此不需要再指定 -b
选项。
如果 dir1 目录已经存在 file1 文件,那么会生成一个备份文件 file1.bak,然后再发生文件复制。
其实 cp 命令有几种内置的生成备份文件的方式,通过 --backup
选项指定,有如下几个值
simple/never
: 备份后缀名为波浪符(~),这是默认方式。numbered/t
: 备份后缀为数字,例如 ~1~。existing/nil
: 如果已经存在数字备份的文件,那么就使用数字后缀,否则使用波浪符后缀。
文件的自我备份
最后介绍一个在 bash shell 中,一个比较有意思的事情,文件自我备份。
$ cp -b file1 file1
cp: 'file1' and 'file1' are the same file
这个命令表示在当前目录下,把 file1 复制为 file1,并且 -b
选项表示生成备份文件。但是这个命令无法执行,可以通过 -f
选项强制执行
$ cp -vfb hello.c hello.c
'hello.c' -> 'hello.c~'
注意,如果你掌握了 cp 命令,其实也就是掌握了 mv 命令,本方介绍的东西都适用于 mv 命令。