如何在Linux中将大文本文件拆分为较小的文件

时间:2020-03-05 15:29:43  来源:igfitidea点击:

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”检查此工具的手册页,以获取有关此信息的更多信息。