如何在Linux中将大文本文件拆分为较小的文件
Linux有几个实用程序可将大文件分解为小文件。
Split和csplit是用于此目的的两个常用命令。
这些实用程序将有助于分解较大的日志文件,甚至将文件存档,以使其尺寸更小。
这样可以方便地将大文件拆分为较小的大小,从而使其适合USB等较小的媒体存储设备,从而达到我们的目的。
通过这种技术,我们甚至可以加快网络文件的传输速度,因为小文件的并行传输通常更快。
在本教程中,我将详细说明如何使用这些拆分和csplit实用程序分解Linux中的大文件。
分割
要将大文件拆分为较小的文件,我们可以在Linux中使用此命令实用程序。
Syntax split [options] filename prefix
我们可以将文件名替换为要拆分的大文件的名称。
并以我们希望给小输出文件的名称加上“ prefix”。
我们可以排除[选项],或者将其替换为以下任一选项:
-a –suffix-length=N use suffixes of length N (default 2) -b –bytes=SIZE put SIZE bytes per output file -C –line-bytes=SIZE put at most SIZE bytes of lines per output file -d –numeric-suffixes use numeric suffixes instead of alphabetic -l –lines=NUMBER put NUMBER lines per output file
split命令将为每个输出文件提供创建的名称前缀,并在其末尾添加扩展名以指示其顺序。
缺省情况下,split命令将aa添加到第一个输出文件,然后对后继文件通过字母继续到'zz'。
默认情况下,大多数系统使用“ x”作为前缀。
分割范例
Split命令将文件分成每个文件n行,并将文件命名为'PREFIXaa,PREFIXab,PREFIXac等。
默认情况下,PREFIX为'x',每个文件的行数为'1000'。
默认情况下将文件分割成多个部分
我有我的日志文件,即1099行的系统日志,让我们使用该命令分割日志文件后查看其状态。
# cat systemlog | wc -l 1099 # split systemlog # ll total 160 -rw-rw-r-- 1 root root 76294 Mar 25 12:02 systemlog -rw-r--r-- 1 root root 68251 Mar 25 12:07 xaa -rw-r--r-- 1 root root 8043 Mar 25 12:07 xab # cat xaa | wc -l 1000 # cat xab | wc -l 99
该命令将日志文件分为两个文件“ xaa和xab”,第一个文件有1000行,并将剩余的文件转储到第二个文件中。
根据行数分割文件
我们可以使用-l选项根据行数将文件分成多个部分。
其中我将1099行的“系统日志”文件拆分为每个200行的较小文件。
让我们看一下相同的命令:
# split -l 200 systemlog # ll total 172 -rw-rw-r-- 1 root root 76294 Mar 25 12:02 systemlog -rw-r--r-- 1 root root 14369 Mar 25 12:16 xaa -rw-r--r-- 1 root root 12795 Mar 25 12:16 xab -rw-r--r-- 1 root root 13566 Mar 25 12:16 xac -rw-r--r-- 1 root root 13681 Mar 25 12:16 xad -rw-r--r-- 1 root root 13840 Mar 25 12:16 xae -rw-r--r-- 1 root root 8043 Mar 25 12:16 xaf # cat xaa | wc -l; cat xab | wc -l; cat xac | wc -l; cat xad | wc -l; cat xae | wc -l; cat xaf | wc -l 200 200 200 200 200 99
我们可以看到该命令已将我的日志文件分为五个较小的文件,每个文件有200行,最后一个有剩余文件。
将大文件分割成500MB文件
我们可以使用选项-b指定所需的大小限制以分割文件。
请参阅此命令,该命令用于将我的“ 1GB Apache日志”文件分为两个500MB文件。
# split -b 500MB httpd.log # ll -lh total 1.9G -rw-r--r-- 1 root root 954M Mar 25 12:35 httpd.log -rw-r--r-- 1 root root 477M Mar 25 12:38 xaa -rw-r--r-- 1 root root 477M Mar 25 12:38 xab
使用给定的前缀将一个大文件拆分为200MB的文件
我们可以使用选项-b来指定200M文件大小和所需的前缀作为第二个参数。
请在下面查看我用于将1GB Apache日志拆分为200MB文件(带有名为“ split.log”的前缀)的命令:
# split -b 200M httpd.log split.log # ll -lh total 1.9G -rw-r--r-- 1 root root 954M Mar 25 12:35 httpd.log -rw-r--r-- 1 root root 200M Mar 25 12:52 split.logaa -rw-r--r-- 1 root root 200M Mar 25 12:52 split.logab -rw-r--r-- 1 root root 200M Mar 25 12:52 split.logac -rw-r--r-- 1 root root 200M Mar 25 12:52 split.logad -rw-r--r-- 1 root root 154M Mar 25 12:52 split.logae
在此示例中,我们可以看到我的日志文件被分解为具有我所需的前缀的200MB文件。
分割文件并用数字命名
我们可以使用选项-d来命名后缀为00、01、02等的文件,以此类推,而不是aa,ab,ac。
请参阅以下命令,该命令用于将我的1GB Apache日志分割为200MB的文件(带有名为log的前缀),并使用-d选项(而不是以下字母)在后缀中添加数字:
# split -d -b 200M httpd.log log # ll -lh total 1.9G -rw-r--r-- 1 root root 954M Mar 25 12:35 httpd.log -rw-r--r-- 1 root root 200M Mar 25 12:58 log00 -rw-r--r-- 1 root root 200M Mar 25 12:58 log01 -rw-r--r-- 1 root root 200M Mar 25 12:58 log02 -rw-r--r-- 1 root root 200M Mar 25 12:58 log03 -rw-r--r-- 1 root root 154M Mar 25 12:58 log04
我们可以使用命令“ man split”来查看split命令的手册页,以了解更多信息。
Csplit
Csplit是另一个命令实用程序,它将单个文件分成由上下文行确定的多个文件。
语法
csplit [option]... filename pattern.
csplit创建的文件通常具有以下格式的名称
xx号
其中number是一个两位十进制数字,从零开始,对于csplit创建的每个新文件,它递增一。
csplit还显示它创建为输出的每个文件的大小(以字节为单位)。
Options -A, uses uppercase letters in place of numbers in the number portion of output file names like xxAA, xxAB, and so on. -a, uses lowercase letters in place of numbers in the number portion of output file names like xxaa, xxab, and so on. -f prefix, specifies a prefix to use in place of the default xx when naming files. If prefix causes a file name longer than NAME_MAX bytes an error occurs and csplit exits without creating any files. -k, leaves all created files intact. Normally, when an error occurs, csplit removes files that it has created. -n number, specifies the number of digits in the number portion of created file names. -s, suppresses the display of file sizes.
Csplit示例
默认情况下,csplit在输出中生成的文件以“ xx”作为前缀,并且在输出中生成的数字是命令生成的文件的字节数。
根据行数分割文件
我有一个包含8行域名的文件,我的要求是在第四行拆分该文件,然后可以通过在命令和文件名后传递“ 4”作为命令行参数来完成此操作。
For example, in our case, domainslist contains the following information: # cat domainslist domain1.com domain2.com domain3.com domain4.com domain5.com domain6.com domain7.com domain8.com
通过将4作为命令行参数传递,此命令将在第4行拆分“ domainslist”文件。
输出中产生的数字是命令产生的文件的字节数。
显然,在输出中产生了两个文件,即xx00和xx01.
# csplit domainslist 4 36 60 # ll total 20 -rw-r--r-- 1 root root 96 Mar 25 14:08 domainslist -rw-r--r-- 1 root root 36 Mar 25 14:08 xx00 -rw-r--r-- 1 root root 60 Mar 25 14:08 xx01 # cat xx00 domain1.com domain2.com domain3.com # cat xx01 domain4.com domain5.com domain6.com
使用正则表达式分割文件
我们可以在csplit命令中使用正则表达式。
例如,在前一种情况下,如果我们希望该命令再重复一次模式,则可以使用以下命令来执行此操作:
# csplit domainslist 4 {1} 36 48 12 # ll total 24 -rw-r--r-- 1 root root 96 Mar 25 14:08 domainslist -rw-r--r-- 1 root root 36 Mar 25 15:13 xx00 -rw-r--r-- 1 root root 48 Mar 25 15:13 xx01 -rw-r--r-- 1 root root 12 Mar 25 15:13 xx02
在这种情况下,我们可以获得三个输出文件。
# cat xx00 domain1.com domain2.com domain3.com # cat xx01 domain4.com domain5.com domain6.com domain7.com # cat xx02 domain8.com
我们可以使用“星号通配符{*}”告诉csplit尽可能多地重复进行拆分。
分割具有给定前缀的文件
默认情况下,csplit分散文件并生成输出文件,以xx作为前缀。
但是,如果需要,可以在命令行中使用带有必需前缀的'option -f'更改默认前缀。
例如,以下命令将产生以“ domain”作为前缀的文件。
# csplit domainslist 4 {1} -f domain 36 48 12 # ll total 24 -rw-r--r-- 1 root root 36 Mar 25 15:16 domain00 -rw-r--r-- 1 root root 48 Mar 25 15:16 domain01 -rw-r--r-- 1 root root 12 Mar 25 15:16 domain02 -rw-r--r-- 1 root root 96 Mar 25 14:08 domainslist
通过取消匹配输入模式的行来分割文件
此csplit命令提供了一个选项,可取消匹配输入模式的行。
有问题的选项是'--suppress-matched'。
例如,以下命令在第4行拆分我们的文件(xx00最多包含第3行,而xx11则包含除第4行以外的其余行)。
# csplit --suppress-matched domainslist 4 36 48 # ll total 20 -rw-r--r-- 1 root root 96 Mar 25 14:08 domainslist -rw-r--r-- 1 root root 36 Mar 25 15:27 xx00 -rw-r--r-- 1 root root 48 Mar 25 15:27 xx01 # cat xx00 domain1.com domain2.com domain3.com # cat xx01 domain5.com domain6.com domain7.com
自定义输出文件名称中的位数
默认情况下,输出文件名中前缀后的位数为2.
我们可以使用此“选项-n”来自定义输出文件名中前缀后的位数。
例如,如果我们要使用诸如xx001之类的名称,则可以使用命令行选项,该选项要求输入数字表示“ -n 3”之类的数字,如下所示:
# csplit -n 3 domainslist 4 36 60 # ll -rw-r--r-- 1 root root 96 Mar 25 14:08 domainslist -rw-r--r-- 1 root root 36 Mar 25 15:34 xx000 -rw-r--r-- 1 root root 60 Mar 25 15:34 xx001
发生错误时强制csplit保存输出文件
默认情况下,csplit会删除在出现任何错误情况时创建的输出文件。
但是,如果要通过在命令中使用“ -k选项”来强制保存此输出文件。
请检查此示例,以了解使用-k选项和不使用-k选项的情况下该命令的执行差异。
默认情况下,csplit会删除在出现任何错误情况时创建的输出文件。
但是,我们可以通过在命令中使用“ -k”选项来强制保存此输出文件。
请检查此示例,以了解使用-k选项和不使用-k选项的情况下执行此命令的区别。
在第一个示例中,该命令用于在第3行上拆分文件“ domainslist”,并像这样重复两次命令,这意味着它也应在第3行上拆分第二个文件,并应再次重复。
但是由于源文件只有八行,因此在第一次拆分后,它会重复一次,但由于范围不足而无法迭代两次。
因此,由于此错误,不会生成任何输出文件。
# csplit domainslist 3 {2} 24 36 36 csplit: ‘3’: line number out of range on repetition 2 # ll total 12 drwxr-xr-x 2 root root 4096 Mar 25 15:41 ./ drwxr-xr-x 4 root root 4096 Mar 25 14:07 ../ -rw-r--r-- 1 root root 96 Mar 25 14:08 domainslist
但是,当我们使用-k选项执行相同的命令时,不会删除输出文件。
请查看以下结果:
# csplit -k domainslist 3 {2} 24 36 36 csplit: ‘3’: line number out of range on repetition 2 # ll total 24 -rw-r--r-- 1 root root 96 Mar 25 14:08 domainslist -rw-r--r-- 1 root root 24 Mar 25 15:41 xx00 -rw-r--r-- 1 root root 36 Mar 25 15:41 xx01 -rw-r--r-- 1 root root 36 Mar 25 15:41 xx02 # cat xx00 domain1.com domain2.com # cat xx01 domain3.com domain4.com domain5.com # cat xx02 domain6.com domain7.com domain8.com
我们可以使用“ man csplit”检查此工具的手册页,以获取有关此信息的更多信息。