简介
split
命令可以按照指定的方式将文本文件分割成多个子文件,下面就来详细介绍其用法。
使用用法及参数详解
可以以如下形式调用 split
命令:
split [OPTION]… [ FILE [PREFIX]]
若 FILE
未指定或者指定为 -
,则从标准输入读取数据进行分割。PREFIX
的默认值为 x
。
若不指定任何参数,则以1000行大小为单位对文件进行分割,分割后生成的输出文件以 xaa、xab、xac、……xaz、xba、xbb 这样的形式命名。
split
命令包含如下选项:
-
-a:
指定输出文件的文件名的后缀的长度,默认长度为2。
--suffix-length=N
生成长度为N的后缀。--additional-suffix=SUFFIX
在文件名的后缀后再添加额外的后缀。
-
-b SIZE
按照字节进行分割,每个输出文件包含输入中的 SIZE 个字节。SIZE 可以是一个整数,后面可选地跟着如下单位之一:
'b' => 512 ("blocks") 'KB' => 1000 (KiloBytes) 'K' => 1024 (KibiBytes) 'MB' => 1000*1000 (MegaBytes) 'M' => 1024*1024 (MebiBytes) 'GB' => 1000*1000*1000 (GigaBytes) 'G' => 1024*1024*1024 (GibiBytes)
T
、P
、E
、Z
和Y
等等。 -
-C SIZE
在不超过 SIZE 字节大小的情况下,将尽可能多的完整行输入到每个输出文件中。大于 SIZE 字节的单个行被分成多个文件。SIZE 的格式与
-b SIZE
选项相同。 -
-d
--numeric-suffixes[=FROM]
使用数字形式的后缀,默认从 0 开始。如果指定了
FROM
,则从FROM
开始。 -
-e
在使用
-n
选项时不生成空的输出文件。 -
—filter=COMMAND
将输出当做Shell 命令
COMMAND
的输入,文件名为$FILE
。使用此选项,输出将不会写入文件中,而是通过管道将其作为
COMMAND
的输入。COMMAND
应该使用$FILE
环境变量,该变量在每次调用COMMAND
时均被设置为不同的输出文件名。 -
-l LINES
按照行进行分割,每个输出文件包含输入中的 LINES 行。
-
-n
生成块(CHUNKS)输出文件。
N
将输入按照大小分割成N
份。K/N
不进行实际的分割,将N
份中的第K
份文件的内容打印到标准输出。l/N
分割成N
个文件,但不分割行。l/K/N
不进行实际分割,将N
份中的第K
份文件的内容打印到标准输出,不会分割行。r/N
与-l
选项类似,但是使用循环的方式分割。例如,如果原文件共6行,当N
为3时,第一份文件包含原文件的1,4行,第二份文件包含原文件的2,5行,第三份文件包含原文件的3,6行。r/K/N
不进行实际的分割,将按照r
标记指定的形式将N
份中的第K
份文件的内容打印到标准输出。
注意:
-b
,-l
,-C
,-n
四个选项是互斥的。
-b
选项与-C
选项的区别是,前者进行分割时,可能会将一行分割到多个文件中,而后者进行分割时会保持行的完整性
-
-t
指定用于替换默认的记录分隔符(换行符)的字符(串)。
\0
表示空字符(NUL)。注意:
该选项仅在较新的版本中可以使用,可以通过
--help
选项查看是否支持该选项。 -
-u
立即使用
-n r/…
模式复制输入到输出。 -
–verbose
在打开每个输出文件之前打印诊断信息。
示例
使用如下命令生成一个包含7999行数据的文本
$ seq -f 'user%04g@163.com' 1 7999 > mail.txt
使用不加参数的 split
命令将该文件进行分割,则会将该文件分割为8个文件,每个文件中包含1000行数据:
$ split mail.txt
$ ls x*
xaa xab xac xad xae xaf xag xah
将文件 mail.txt
分割成多个文件,每个文件最多包含2000行:
$ split -l 2000 mail.txt
$ ls x*
xaa xab xac xad
$ wc -l x*
2000 xaa
2000 xab
2000 xac
1999 xad
7999 总用量
将文件 mail.txt
分割成多个文件,每个文件最多包含 2000 行,且以数字作为后缀:
$ split -d -l 2000 mail.txt
$ ls x*
x00 x01 x02 x03
将文件 mail.txt
分割成多个文件,每个文件最多包含 2000 行,且以3 位数字作为后缀,后缀的数字从 100 开始:
split -a 3 --numeric-suffixes=100 -l 2000 mail.txt
$ ls x*
x100 x101 x102 x103
注意:
通过
--numeric-suffixes=FROM
选项指定的后缀的起始值与后缀的默认长度或通过-a
选项显式指定的后缀的长度不能冲突:
- 若
FROM
的长度大于默认的后缀长度或者显式指定的后缀长度,则会报错;$ wc -l mail.txt 7999 mail.txtt $ split --numeric-suffixes=100 -l 2000 mail.txt split: numerical suffix start value is too large for the suffix length
- 若 计算出的某个输出文件的后缀的长度大于默认的后缀长度或者显式指定的后缀长度,则不会生成该输出文件;
$ wc -l mail.txt 7999 mail.txtt $ split --verbose -a 1 --numeric-suffixes=1 -l 500 mail.txt 正在创建文件"x1" 正在创建文件"x2" 正在创建文件"x3" 正在创建文件"x4" 正在创建文件"x5" 正在创建文件"x6" 正在创建文件"x7" 正在创建文件"x8" 正在创建文件"x9" split: 已排除输出文件后缀 $ ls x* x1 x2 x3 x4 x5 x6 x7 x8 x9 $ wc -l x* 500 x1 500 x2 500 x3 500 x4 500 x5 500 x6 500 x7 500 x8 500 x9 4500 总用量 # 由于大于 '9' 的后缀的长度为 2, 超过了指定的后缀的长度 1 # 所以没有创建文件名为 x10、x11 ... 那些文件
将文件 mail.txt
分割成多个文件,每个文件最大为20K:
$ split -b 20K mail.txt
$ ls x*
xaa xab xac xad xae xaf xag
$ du -h x*
20K xaa
20K xab
20K xac
20K xad
20K xae
20K xaf
16K xag
将文件 mail.txt
分割成多个文件,每个文件最大为20K,且文件名以 mail
作为前缀,以2位数字作为后缀:
$ split -b 20K -d -a 2 mail.txt mail
$ ls mail0*
mail00 mail01 mail02 mail03 mail04 mail05 mail06
$ du -h mail0*
20K mail00
20K mail01
20K mail02
20K mail03
20K mail04
20K mail05
16K mail06
将文件 mail.txt
分割成多个文件,每个文件最大为20K,且文件名以 mail
作为前缀,3位数字作为后缀,再附加一个额外的后缀 .txt
:
$ split -b 20K -d --suffix-length=3 --additional-suffix=.txt mail.txt mail
$ ls mail0*
mail000.txt mail001.txt mail002.txt mail003.txt mail004.txt mail005.txt mail006.txt
创建一个大小约为27M的文件 user.txt
:
$ seq -f '%0.f' 1 144000 > user.txt; done
$ du -h * user.txt
27M user.txt
通过下面的例子,来演示下 -b
选项的 K,M,G,T,P,E,Z,Y
参数和 KB,MB,GB,TB,PB,EB,ZB,YB
参数的区别:
将文件 user.txt
分割成多个文件,每个文件最大为10M :
$ split -b 10M user.txt
$ ls x*
xaa xab xac
$ du -h x*
10M xaa
10M xab
6.5M xac
将文件 user.txt
分割成多个文件,每个文件最大为10MB:
$ split -b 10MB user.txt
$ ls x*
xaa xab xac
$ du -h x*
9.6M xaa
9.6M xab
7.4M xac
可以看到,使用第一种方法进行分割后,每个文件的实际大小最大为10M,而使用第二种方法进行分割后,每个文件的实际大小最大是9.6M,即 10MB。
将文件 user.txt
按大小分割成3份:
$ split -n 3 user.txt
$ ls x*
xaa xab xac
$ du -h x*
8.9M xaa
8.9M xab
8.9M xac
通过 --filter
选项对输出进行处理:
# 注意,执行下面的命令需要几秒钟,并不是没有响应,不要强制退出
$ split -n 3 -d --filter='xz > $FILE.xz' user.txt user_part_
$ ls *.xz
user_part_00.xz user_part_01.xz user_part_02.xz
$ du -h *.xz
124K user_part_00.xz
120K user_part_01.xz
128K user_part_02.xz
$ xz -l *.xz
Strms Blocks Compressed Uncompressed Ratio Check Filename
1 1 121.7 KiB 9,013.3 KiB 0.014 CRC64 user_part_00.xz
1 1 116.6 KiB 9,013.3 KiB 0.013 CRC64 user_part_01.xz
1 1 125.3 KiB 9,013.3 KiB 0.014 CRC64 user_part_02.xz
-------------------------------------------------------------------------------
3 3 363.5 KiB 26.4 MiB 0.013 CRC64 3 files
有一个包含服务器连接的日志文件 server.log
$ cat server.log
SERVER-1
[connection] 192.168.0.1 success
[connection] 192.168.0.2 failed
[disconnect] 192.168.0.3 pending
[connection] 192.168.0.4 success
SERVER-2
[connection] 192.168.0.1 failed
[connection] 192.168.0.2 failed
[disconnect] 192.168.0.3 success
[connection] 192.168.0.4 failed
SERVER-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
不实际分割文件 server.log
,将3份中的第二份的内容打印至标准输出:
$ split -n 2/3 server.log
SERVER-2
[connection] 192.168.0.1 failed
[connection] 192.168.0.2 failed
[disconnect] 192.168.0.3 success
[connection] 192.168.0.4 failed
# 注意,第一行是空行
将文件分割成3等份,保持行的完整性
$ split -n l/3 server.log
不实际分割文件 server.log
,将3份中的第二份的内容打印至标准输出(保持了行的完整性):
$ split -n l/2/3 server.log
SERVER-2
[connection] 192.168.0.1 failed
[connection] 192.168.0.2 failed
[disconnect] 192.168.0.3 success
[connection] 192.168.0.4 failed
使用循环模式 r
将 server.log
分割成 3 份:
$ split -n r/3 -a 1 -d --additional-suffix=.log server.log part
$ ls part*
part0.log part1.log part2.log
$ cat part0.log
SERVER-1
[disconnect] 192.168.0.3 pending
[connection] 192.168.0.1 failed
[connection] 192.168.0.4 failed
[connection] 192.168.0.2 pending
$ cat part1.log
[connection] 192.168.0.1 success
[connection] 192.168.0.4 success
[connection] 192.168.0.2 failed
SERVER-3
[disconnect] 192.168.0.3 pending
$ cat part2.log
[connection] 192.168.0.2 failed
SERVER-2
[disconnect] 192.168.0.3 success
[connection] 192.168.0.1 pending
[connection] 192.168.0.4 failed