有时我们需要将一个文件分割成多个部分,或者将一个文件的各个部分重新合并成为一个文件,该怎样做呢?
分割与重新合并文件时,我们分别需要用到 split 和 cat 命令。
分割文件
假设我们在当前目录下只有一个文件 mysong.mp3,其大小为 5M:
Default
$ ls -lh
total 5.0M
-rw-rw-r-- 1 lee lee 5.0M Nov 30 15:43 mysong.mp3
1
2
3
$ls-lh
total5.0M
-rw-rw-r--1leelee5.0MNov3015:43mysong.mp3
假设我们要把它分为大小相等的五部分,并以数字作为后缀。我们需到用到 split 命令。其基本句法为:
Default
$ split [选项] [输入] [输出文件名前缀]
1
$split[选项][输入][输出文件名前缀]
因此在这里,我们可以这样做:
Default
$ split -n 5 -d mysong.mp3 mysong.mp3.part
$ ls -lh
total 10M
-rw-rw-r-- 1 lee lee 5.0M Nov 30 15:43 mysong.mp3
-rw-rw-r-- 1 lee lee 1019K Nov 30 15:58 mysong.mp3.part00
-rw-rw-r-- 1 lee lee 1019K Nov 30 15:58 mysong.mp3.part01
-rw-rw-r-- 1 lee lee 1019K Nov 30 15:58 mysong.mp3.part02
-rw-rw-r-- 1 lee lee 1019K Nov 30 15:58 mysong.mp3.part03
-rw-rw-r-- 1 lee lee 1019K Nov 30 15:58 mysong.mp3.part04
1
2
3
4
5
6
7
8
9
$split-n5-dmysong.mp3mysong.mp3.part
$ls-lh
total10M
-rw-rw-r--1leelee5.0MNov3015:43mysong.mp3
-rw-rw-r--1leelee1019KNov3015:58mysong.mp3.part00
-rw-rw-r--1leelee1019KNov3015:58mysong.mp3.part01
-rw-rw-r--1leelee1019KNov3015:58mysong.mp3.part02
-rw-rw-r--1leelee1019KNov3015:58mysong.mp3.part03
-rw-rw-r--1leelee1019KNov3015:58mysong.mp3.part04
假设我们要上传一个附件,其大小不能超过 0.9M,通过计算:
0.9 x 1024 = 921.6
(为了保险起见,我们舍去了小数点后的值)
Default
$ rm mysong.mp3.part0{0..4}
$ ls
mysong.mp3
$ split -b 921k -d mysong.mp3 mysong.mp3.part
lee@lee-work ~/test $ ls
mysong.mp3 mysong.mp3.part01 mysong.mp3.part03 mysong.mp3.part05
mysong.mp3.part00 mysong.mp3.part02 mysong.mp3.part04
lee@lee-work ~/test $ ls -lh
total 10M
-rw-rw-r-- 1 lee lee 5.0M Nov 30 15:43 mysong.mp3
-rw-rw-r-- 1 lee lee 921K Nov 30 16:09 mysong.mp3.part00
-rw-rw-r-- 1 lee lee 921K Nov 30 16:09 mysong.mp3.part01
-rw-rw-r-- 1 lee lee 921K Nov 30 16:09 mysong.mp3.part02
-rw-rw-r-- 1 lee lee 921K Nov 30 16:09 mysong.mp3.part03
-rw-rw-r-- 1 lee lee 921K Nov 30 16:09 mysong.mp3.part04
-rw-rw-r-- 1 lee lee 490K Nov 30 16:09 mysong.mp3.part05
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$rmmysong.mp3.part0{0..4}
$ls
mysong.mp3
$split-b921k-dmysong.mp3mysong.mp3.part
lee@lee-work~/test$ls
mysong.mp3mysong.mp3.part01mysong.mp3.part03mysong.mp3.part05
mysong.mp3.part00mysong.mp3.part02mysong.mp3.part04
lee@lee-work~/test$ls-lh
total10M
-rw-rw-r--1leelee5.0MNov3015:43mysong.mp3
-rw-rw-r--1leelee921KNov3016:09mysong.mp3.part00
-rw-rw-r--1leelee921KNov3016:09mysong.mp3.part01
-rw-rw-r--1leelee921KNov3016:09mysong.mp3.part02
-rw-rw-r--1leelee921KNov3016:09mysong.mp3.part03
-rw-rw-r--1leelee921KNov3016:09mysong.mp3.part04
-rw-rw-r--1leelee490KNov3016:09mysong.mp3.part05
-b: 每个输出文件的大小,其单位可为 KB 1000, K 1024, MB 1000*1000, M 1024 及 G, T, P, E, Z, Y。
-d: 使用数字后缀而非字母。
-n: 生成 N 个部分的输出文件。
合并文件
假设我们需要将上面的 mysong.mp3.part0{0..5} 重新合并为一个文件,需要使用 cat 命令。cat 为 concatenate 的缩略词,用于联结多个文件或标准输入并显示为标准输出。其基本句式为:
Default
$ cat [选项] [文件]
1
$cat[选项][文件]
对于这个例子,我们可以这样做:
Default
$ cat mysong.mp3.part* > mysong-reassembled.mp3
$ ls
mysong.mp3 mysong.mp3.part01 mysong.mp3.part03 mysong.mp3.part05
mysong.mp3.part00 mysong.mp3.part02 mysong.mp3.part04 mysong-reassembled.mp3
1
2
3
4
$catmysong.mp3.part*>mysong-reassembled.mp3
$ls
mysong.mp3mysong.mp3.part01mysong.mp3.part03mysong.mp3.part05
mysong.mp3.part00mysong.mp3.part02mysong.mp3.part04mysong-reassembled.mp3
这里我们再延伸地讲一下 cat 的用法。
cat 会读入你给它的任何文件(作为参数),然后会逐一将各个文件输出为标准输出。它会联结任何你给它的文件(作为参数)。
举个简单的例子:
Default
$ cat
1
$cat
我们会看到,cat 并没有把 shell 提示符还给我们,而是一直“停”在那里。这是怎么回事?当我们不给 cat 任何参数时运行 cat 时, cat 会从标准输出中读入,以现在的情况,就是你的键盘。也就是说,cat 仍然在等待标准输入,任何我们键入的字符都会发送给 cat,在你敲下回车时,cat 就会像往常一样将标准输入显示输出到标准输出:
Default
$ cat
nani?
nani?
1
2
3
$cat
nani?
nani?
许多网上的例子在我们想要读入文件的内容时总是告诉我们使用 cat。这是不必要的!cat 只在联结多个文件或快速地在命令行下查看一文件内容时是实用的。在脚本中不要使用 cat 通过管道将一文件输出到命令。请记住这个提示。在不必要的时候使用 cat 只会创建额外的进程,而且会拖慢运行速度,因为 cat 不能够分辨它读入的文件的类型与作用。
如下面的这个例子(来自链接):
Default
$ cat apple.txt
core
worm seed
jewel
$ cat apple.txt | wc #bad,bad,bad!
3 4 21
$
1
2
3
4
5
6
7
$catapple.txt
core
wormseed
jewel
$catapple.txt|wc#bad,bad,bad!
3421
$
在这里我们只需要将 apple.txt 这个文本作为 wc 的参数,或者使用重定向 wc < apple.txt。使用 cat 不仅全无必要,而且导致了额外进程的运行。
还有一点需要提醒的是,不要用归档命令如(rar)去解压使用 split 分割的压缩档案,需要使用 cat 合并压缩文件后再正常解压,否则会出错。