有时候必须把文件分割成多个更小的片段。很久以前,我们必须分割文件,才能将大量数据放入多张软盘中。不过如今我们分割文件就是出于其他目的了,比如为提高可读性、生成日志以及发送有大小限制的E-mail附件。在这则攻略中我们会看到如何将文件分割成不同的大小。
2.11.1 工作原理
split命令可以用来分割文件。该命令接受文件名作为参数,然后创建出一系列体积更小的文件,其中依据字母序排在首位的那个文件对应于原始文件的第一部分,排在次位的文件对应于原始文件的第二部分,以此类推。
例如,通过指定分割大小,可以将 100 KB 的文件分成一系列 10 KB 的小文件。在split命令中,
除了k(KB),我们还可以使用M(MB)、G(GB)、c(byte)和w(word)。
$ split -b 10k data.file$ lsdata.file xaa xab xac xad xae xaf xag xah xai xaj
上面的命令将data.file分割成了 10 个大小为 10 KB 的文件。这些新文件以 xab 、xac 、xad 的形式命名。split默认使用字母后缀。如果想使用数字后缀,需要使用-d选项。此外,-a length 可以指定后缀长度:
$ split -b 10k data.file -d -a 4$ lsdata.file x0009 x0019 x0029 x0039 x0049 x0059 x0069 x0079
2.11.2 补充内容
来看看split命令的其他选项。
为分割后的文件指定文件名前缀
之前那些分割后的文件名都是以x作为前缀。如果要分割的文件不止一个,我们自然希望能自己命名这些分割后的文件,这样才能够知道这些文件分别属于哪个原始文件。这可以通过提供一个前缀作为最后一个参数来实现。
这次我们使用split_file作为文件名前缀,重新执行上一条命令:
$ split -b 10k data.file -d -a 4 split_file$ lsdata.file split_file0002 split_file0005 split_file0008strtok.csplit_file0000 split_file0003 split_file0006 split_file0009split_file0001 split_file0004 split_file0007
如果不想按照数据块大小,而是根据行数来分割文件的话,可以使用-l no_of_lines:
#分割成多个文件,每个文件包含10行$ split -l 10 data.file
csplit实用工具能够基于上下文来分隔文件。它依据的是行计数或正则表达式。这个工具对于日志文件分割尤为有用。
看一个日志文件示例:
$ cat server.logSERVER-1[connection] 192.168.0.1 success[connection] 192.168.0.2 failed[disconnect] 192.168.0.3 pending[connection] 192.168.0.4 successSERVER-2[connection] 192.168.0.1 failed[connection] 192.168.0.2 failed[disconnect] 192.168.0.3 success[connection] 192.168.0.4 failedSERVER-3[connection] 192.168.0.1 pending[connection] 192.168.0.2 pending[disconnect] 192.168.0.3 pending[connection] 192.168.0.4 failed
我们需要将这个日志文件分割成server1.log、server2.log和server3.log,这些文件的内容分别取自原文件中不同的SERVER部分。实现方法如下:
$ csplit server.log /SERVER/ -n 2 -s {*} -f server -b "%02d.log"$ rm server00.log$ lsserver01.log server02.log server03.log server.log
下面是这个命令的详细说明:
/SERVER/用来匹配特定行,分割过程即从此处开始。/[REGEX]/用于描述文本模式。它从当前行(第一行)一直复制到(但不包括)包含SERVER的匹配行。{*}表示根据匹配重复执行分割操作,直到文件末尾为止。可以用{整数}的形式来指定分割执行的次数。-s使命令进入静默模式,不打印其他信息。-n指定分割后的文件名后缀的数字个数,例如01、02、03等。-f指定分割后的文件名前缀(在上面的例子中,server就是前缀)。-b指定后缀格式。例如%02d.log,类似于C语言中printf的参数格式。在这里:**文件名=前缀 + 后缀**,也就是server + %02d.log。
因为分割后得到的第一个文件没有任何内容(匹配的单词就位于文件的第一行中),所以我们删除server00.log。
