简介
本文将展示linux的split和csplit命令的几种使用场景。split和csplit命令可以用来在不同的场景拆分或者组合文件。
split只能通过文件大小拆分文件。csplit是split的扩展,可以通过匹配来拆分文件。匹配的方式可以为模式匹配、正则匹配以及字符串匹配。
示例
1 csplit使用正则匹配
使用csplit命令,可以通过正则匹配来分割文件。
命令格式:
csplit input_file '正则表达式' '{*}'
# input_file 待拆分的文件
# '{*}' 重复执行前面的表达式,直至结束
基础实例1
我们假设文件内容如下。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
按照<dependency>进行切分,这样每个文件都是<dependency>...</dependency>。
示例:
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ csplit test.xml '/^<dependency>$/' '{*}'
0
134
131
128
160
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ ll
total 20
-rw-r--r-- 1 yunzhong yunzhong 553 Nov 27 10:34 test.xml
-rw-r--r-- 1 yunzhong yunzhong 0 Nov 27 14:25 xx00
-rw-r--r-- 1 yunzhong yunzhong 134 Nov 27 14:25 xx01
-rw-r--r-- 1 yunzhong yunzhong 131 Nov 27 14:25 xx02
-rw-r--r-- 1 yunzhong yunzhong 128 Nov 27 14:25 xx03
-rw-r--r-- 1 yunzhong yunzhong 160 Nov 27 14:25 xx04
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx00
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx01
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx00
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx02
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx03
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx04
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
基础实例2
假设我们的文件内容如下:
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat functions
function main1 {
echo "function main1"
}
function main2 {
echo "function main2"
}
function main3 {
echo "function main3"
}
我们需要将每个函数都拆分到单独的文件。如文件内容所示,每个函数的结束都是以大括号和换行。我们可以用这种方式来拆分函数。
命令格式如下:
csplit --elide-empty-files functions '/^}/+2' "{*}"
# /^}/+2 表示正则匹配字符“}”。找匹配后,向后推移两个字符。通过此方式来去掉空行。
# {*} 表示尽可能多的执行匹配。
执行结果:
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ csplit --elide-empty-files functions '/^}/+2' "{*}"
43
43
43
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx00
function main1 {
echo "function main1"
}
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx01
function main2 {
echo "function main2"
}
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx02
function main3 {
echo "function main3"
}
csplit模式匹配
类似于正则匹配,我们可以让csplit进行模式匹配。假设我们有文件。
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat pattern
12345
asdfg
vbn
000
4634
fghvva
a000a
ceqdcad
433214
000
类似于正则匹配,我们通过“000”来拆分文件,且匹配后行+1.
执行命令:
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ csplit --elide-empty-files pattern '/000/+1' {*}
20
18
19
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx00
12345
asdfg
vbn
000
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx01
4634
fghvva
a000a
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx02
ceqdcad
433214
000
3 打印匹配内容
csplit可以打印匹配的内容,可以使用--suppress-matched参数强制输出匹配内容。ubuntu其实默认的就为打印,如上面的例子。
csplit --suppress-matched --elide-empty-files pattern '/000/' {*}
16
12
15
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx00
12345
asdfg
vbn
打印结果说明:每个拆分文件的大小。可能和cat的内容不匹配。因为换行也是字符,但是不可见。
4 删除csplit 和 split产生的空文件
当使用csplit和split命令时,很有可能产生空文件。可以使用参数--elide-empty-files防止空文件产生。
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat pattern
12345
asdfg
vbn
000
4634
fghvva
a000a
ceqdcad
433214
000
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ csplit pattern '/000/+1' {*}
20
18
19
0
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ csplit --elide-empty-files pattern '/000/+1' {*}
20
18
19
如上例子,当使用参数--elide-empty-files,输出的文件没有了“0”。
5 添加输出文件前缀
可以使用参数--prefix,为生成的文件添加前缀。
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ csplit --elide-empty-files --prefix subfile_ pattern '/000/' {*}
16
16
21
4
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ ll
total 40
-rw-r--r-- 1 yunzhong yunzhong 129 Nov 27 20:56 functions
-rw-r--r-- 1 yunzhong yunzhong 57 Nov 27 21:06 pattern
-rw-r--r-- 1 yunzhong yunzhong 16 Nov 28 20:59 subfile_00
-rw-r--r-- 1 yunzhong yunzhong 16 Nov 28 20:59 subfile_01
-rw-r--r-- 1 yunzhong yunzhong 21 Nov 28 20:59 subfile_02
-rw-r--r-- 1 yunzhong yunzhong 4 Nov 28 20:59 subfile_03
6 通过多种匹配拆分文件
早期的版本,csplit通过匹配拆分文件,现在支持传入多个匹配值。例如,一篇文章有多个title,我们可以将多个title作为匹配值。
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat multipattern
title1
content1
title2
content2
title3
content3
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ csplit --elide-empty-files --prefix parts multipattern '/title1/' '/title2/' '/t
itle3/'
16
16
16
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ ll
total 56
-rw-r--r-- 1 yunzhong yunzhong 129 Nov 27 20:56 functions
-rw-r--r-- 1 yunzhong yunzhong 48 Nov 28 21:01 multipattern
-rw-r--r-- 1 yunzhong yunzhong 16 Nov 28 21:03 parts00
-rw-r--r-- 1 yunzhong yunzhong 16 Nov 28 21:03 parts01
-rw-r--r-- 1 yunzhong yunzhong 16 Nov 28 21:03 parts02
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat parts00
title1
content1
7 csplit生成文件设置后缀
默认情况下,csplit使用自定义语法创建拆分后的文件。你可以添加自定义前缀,也可以添加自定义后缀。
下面,我们为每个生成的文件设置后缀".data".
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ csplit --elide-empty-files --prefix=subfile --suffix-format="%d.data" pattern '
/000/' "{*}"
16
16
21
4
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ ll
total 72
-rw-r--r-- 1 yunzhong yunzhong 16 Nov 28 21:06 subfile0.data
-rw-r--r-- 1 yunzhong yunzhong 16 Nov 28 21:06 subfile1.data
-rw-r--r-- 1 yunzhong yunzhong 21 Nov 28 21:06 subfile2.data
-rw-r--r-- 1 yunzhong yunzhong 4 Nov 28 21:06 subfile3.data
在命令中,我们使用了两个参数:
--prefix => 在拆分后创建的所有文件的开始前添加前缀
--suffix => 在拆分后创建的所有文件的末尾添加后缀
我们还可以指定文件的数字编码格式,下面的例子中编号采用两个数字:
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ csplit --elide-empty-files --prefix=subfile --suffix-format="%02d.data" pattern '/000/' "{*}"
16
16
21
4
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ ll
total 32
-rw-r--r-- 1 yunzhong yunzhong 129 Nov 27 20:56 functions
-rw-r--r-- 1 yunzhong yunzhong 48 Nov 28 21:01 multipattern
-rw-r--r-- 1 yunzhong yunzhong 57 Nov 27 21:06 pattern
-rw-r--r-- 1 yunzhong yunzhong 16 Nov 28 21:09 subfile00.data
-rw-r--r-- 1 yunzhong yunzhong 16 Nov 28 21:09 subfile01.data
-rw-r--r-- 1 yunzhong yunzhong 21 Nov 28 21:09 subfile02.data
-rw-r--r-- 1 yunzhong yunzhong 4 Nov 28 21:09 subfile03.data
8 在模式匹配的基础上指定拆分个数
使用split命令,您可以将文件分割为特定的个数,但我们将在后面讨论。这里使用的是csplit命令,我们将基于模式匹配进行拆分,但我们还定义了在拆分文件中必须检查模式的次数。
下面的例子,虽然我们使用模式匹配拆分文件,但是不会重复拆分。因此只会拆分一次,分成两个文件。
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat patterncount
#1 before first pattern
#2 before first pattern
pattern 000
#1 before second pattern
#2 before second pattern
pattern 000
#1 before third pattern
#2 before third pattern
pattern 000
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ csplit --elide-empty-files --digits 1 patterncount '/000/+1' {0}
60
122
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xx1
#1 before second pattern
#2 before second pattern
pattern 000
#1 before third pattern
#2 before third pattern
pattern 000
其中:
{0} 标识不会重复匹配。因此在匹配一次后,不会再继续。如果设置成{1},那么只会重复一次,如下例。三个文件的内容长度分别为:60,6,60
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ csplit --elide-empty-files --digits 1 patterncount '/000/+1' {1}
60
62
60
9 通过行号来拆分文件
我们可以使用参数--lines来指定拆分的文件行数。最后一个文件的行数可能小于等于设定值。
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat patterncount
#1 before first pattern
#2 before first pattern
pattern 000
#1 before second pattern
#2 before second pattern
pattern 000
#1 before third pattern
#2 before third pattern
pattern 000
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ split --lines 5 patterncount
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ ll
total 28
-rw-r--r-- 1 yunzhong yunzhong 110 Nov 28 21:21 xaa
-rw-r--r-- 1 yunzhong yunzhong 72 Nov 28 21:21 xab
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xab
pattern 000
#1 before third pattern
#2 before third pattern
pattern 000
10 按照大小拆分文件
我们可以使用split按照文件的大小来拆分文件。
指定的文件大小可以用单位来标识:
K => KiloBytes
M => megaBytes
G => GigaBytes
代码示例:
split --bytes 1M my_file
11 split命令指定拆分后文件的后缀或扩展
和csplit类似,我们可以为split指定文件后缀,参数为:--additional-suffix
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ split --additional-suffix ".ext" -b 20 patterncount
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ ll
total 60
-rw-r--r-- 1 yunzhong yunzhong 129 Nov 27 20:56 functions
-rw-r--r-- 1 yunzhong yunzhong 48 Nov 28 21:01 multipattern
-rw-r--r-- 1 yunzhong yunzhong 57 Nov 27 21:06 pattern
-rw-r--r-- 1 yunzhong yunzhong 182 Nov 28 21:13 patterncount
-rw-r--r-- 1 yunzhong yunzhong 553 Nov 27 10:34 test.xml
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:26 xaa.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:26 xab.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:26 xac.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:26 xad.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:26 xae.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:26 xaf.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:26 xag.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:26 xah.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:26 xai.ext
-rw-r--r-- 1 yunzhong yunzhong 2 Nov 28 21:26 xaj.ext
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xaa.ext
#1 before first patt
12 split命令拆分文件添加数字编号和后缀
参数--numeric-suffixes可以让split生成的文件带数字编码,且可以和参数--additional-suffix配合使用。
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ split --numeric-suffixes --additional-suffix ".ext" -b 20 patterncount
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ ll
total 60
-rw-r--r-- 1 yunzhong yunzhong 129 Nov 27 20:56 functions
-rw-r--r-- 1 yunzhong yunzhong 48 Nov 28 21:01 multipattern
-rw-r--r-- 1 yunzhong yunzhong 57 Nov 27 21:06 pattern
-rw-r--r-- 1 yunzhong yunzhong 182 Nov 28 21:13 patterncount
-rw-r--r-- 1 yunzhong yunzhong 553 Nov 27 10:34 test.xml
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:29 x00.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:29 x01.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:29 x02.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:29 x03.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:29 x04.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:29 x05.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:29 x06.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:29 x07.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:29 x08.ext
-rw-r--r-- 1 yunzhong yunzhong 2 Nov 28 21:29 x09.ext
13 split 增加前缀
和csplit类似,split可以添加前缀。
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ split --numeric-suffixes --additional-suffix ".ext" -b 20 patterncount prefix_
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ ll
total 60
-rw-r--r-- 1 yunzhong yunzhong 129 Nov 27 20:56 functions
-rw-r--r-- 1 yunzhong yunzhong 48 Nov 28 21:01 multipattern
-rw-r--r-- 1 yunzhong yunzhong 57 Nov 27 21:06 pattern
-rw-r--r-- 1 yunzhong yunzhong 182 Nov 28 21:13 patterncount
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:31 prefix_00.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:31 prefix_01.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:31 prefix_02.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:31 prefix_03.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:31 prefix_04.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:31 prefix_05.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:31 prefix_06.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:31 prefix_07.ext
-rw-r--r-- 1 yunzhong yunzhong 20 Nov 28 21:31 prefix_08.ext
-rw-r--r-- 1 yunzhong yunzhong 2 Nov 28 21:31 prefix_09.ext
14 split指定拆分个数
现在我们使用csplit将模式匹配后的文件拆分为特定的计数,而使用split我们不匹配模式,但我们可以定义拆分后创建的文件的计数。
可以通过参数--number设定拆分个数。
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ split --number 3 patterncount
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ ll
total 32
-rw-r--r-- 1 yunzhong yunzhong 60 Nov 28 21:33 xaa
-rw-r--r-- 1 yunzhong yunzhong 60 Nov 28 21:33 xab
-rw-r--r-- 1 yunzhong yunzhong 62 Nov 28 21:33 xac
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xaa
#1 before first pattern
#2 before first pattern
pattern 000
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xab
#1 before second pattern
#2 before second pattern
pattern 00yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xac
0
#1 before third pattern
#2 before third pattern
pattern 000
15 合并之前的拆分文件
我们可以将之前的拆分文件合并成一个,但不是使用csplit和split。
命令如下:
cat split-files-* > your_new_filename
示例:
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat xa* > patterncountnew
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ cat patterncountnew
#1 before first pattern
#2 before first pattern
pattern 000
#1 before second pattern
#2 before second pattern
pattern 000
#1 before third pattern
#2 before third pattern
pattern 000
yunzhong@DESKTOP-9VB7LN7:/tmp/splitdir$ diff patterncount patterncountnew
通过diff可以看出,两个文件是完全一致的。