Linux常用命令-csplit

命令

csplit

描述

split a file into sections determined by context lines
分割文件

用法

1
csplit [OPTION]... FILE PATTERN...

选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Options:
-b 指定后缀,默认为%02d,即00,01
-f 指定前缀,默认为xx
-k 如果分割出现错误则保留已存在的文件
-n 指定数字长度
-s 静默模式
-z 删除生成的空文件
--suppress-matched 分割文件中不显示匹配到的行,即不显示分割行的内容

PATTERN,可以组合使用
NUM 以指定行号作为分界点分割文件,可以指定多个行作为分界点
/REGEXP/[OFFSET] 正则匹配,将匹配到的行作为分界点分割文件,支持加定位行匹配,支持+-符号
%REGEXP%[OFFSET] 正则匹配,但不包括匹配行之前的内容,即只保存匹配行之后的内容到分割文件中
{N} 重复N次前面的模式匹配
{*} 尽可能多地重复前面的模式匹配

PATTERN示例:
2 指定第2行作为分割行
2 8 指定第2行和第8行作为分割行
/abc/ 指定正则匹配abc的行作为分割行
/b/ {3} 指定匹配b的行作为分割行,并重复匹配3次
/b/ {*} 指定匹配b的行作为分割行,并多次匹配
/^b/+2 指定匹配以b开头的行的后2行作为分隔符
/^c/-2 指定匹配以c开头的行的前2行作为分隔符
%c% 指定匹配c的行作为分割行,保存之后的内容到分割文件中

注意

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# 以第2行作为分界点将文件a分割成两份,其中第2行位于xx01文件中,显示的两个数字表示两个分割文件的大小
$ csplit a 2
2
12
$ ll xx*
-rw-r--r-- 1 root root 2 Feb 15 22:31 xx00
-rw-r--r-- 1 root root 12 Feb 15 22:31 xx01
$ more xx*
::::::::::::::
xx00
::::::::::::::
a
::::::::::::::
xx01
::::::::::::::
b
c
123
abc
# -b指定后缀_
$ csplit -b "_%d" a 2
2
12
$ ls xx*
xx_0 xx_1
$ rm -rf xx*
# 指定后缀.
$ csplit -b ".%d" a 2
2
12
$ ls xx*
xx.0 xx.1
$ rm -rf xx*
# 指定后缀.0
$ csplit -b ".%02d" a 2
2
12
$ ls xx*
xx.00 xx.01
$ rm -rf xx*
# -f指定前缀为文件名本身a
$ csplit -f a a 2
2
12
$ ls a*
a a00 a01
# 指定前缀为文件名加.
$ csplit -f a. a 2
2
12
$ ls a.*
a.00 a.01
# -b指定后缀为.0,-f指定前缀为文件名本身a
$ csplit -b ".%d" -f a a 2
2
12
$ ls a*
a a.0 a.1
$ echo -e "a\nb\nc\nd" > file
# 指定后缀为.00,指定前缀为文件名本身file
$ csplit -b ".%02d" -f file file 2
2
6
$ ls file*
file file.00 file.01

# -n3指定3位数字后缀
$ csplit -n3 a 2
2
12
$ ls xx*
xx000 xx001
# 指定从10行开始分割,但是文件本身只有5行,所以报错,但是会删除原有的分割文件
$ csplit -n3 a 10
csplit: ‘10’: line number out of range
14
$ ls xx*
xx001
# -s静默模式,不显示分割文件的大小
$ csplit -s -n3 a 2
$ ls xx*
xx000 xx001
# -k如果分割出错,则保留原有的分割文件
$ csplit -k -n3 a 10
csplit: ‘10’: line number out of range
14
$ ls xx*
xx000 xx001
$ rm -rf xx*

# 指定多个行分界点
$ seq 1 15 > b
# 如指定第2,8行,将会生成3个文件,xx00包括第1行,xx01包括第2-7行,xx02包括第8-末尾行
$ csplit b 2 8
2
12
22
$ ll xx*
-rw-r--r-- 1 root root 2 Feb 15 23:26 xx00
-rw-r--r-- 1 root root 12 Feb 15 23:26 xx01
-rw-r--r-- 1 root root 22 Feb 15 23:26 xx02
$ more xx*
# {N}表示重复N次前面的匹配,如下表示按每3行来分割文件,重复4次,等同于3 6 9 12 15
$ csplit b 3 {4}
4
6
6
8
9
3
$ ls xx*
xx00 xx01 xx02 xx03 xx04 xx05
$ more xx05
15
# 等同于上面的命令
$ csplit b 3 6 9 12 15
4
6
6
8
9
3
$ rm -rf xx*
# {*}表示多次重复前面的匹配,如下表示按每3行来分割文件,直到文件结尾
# 由于最后不足3行匹配会报错,所以需要加-k选项保留已分割的文件,否则将不会生成任何分割文件
$ csplit -k b 3 {*}
4
6
6
8
9
csplit: ‘3’: line number out of range on repetition 5
3
$ ll xx*
-rw-r--r-- 1 root root 4 Feb 15 23:38 xx00
-rw-r--r-- 1 root root 6 Feb 15 23:38 xx01
-rw-r--r-- 1 root root 6 Feb 15 23:38 xx02
-rw-r--r-- 1 root root 8 Feb 15 23:38 xx03
-rw-r--r-- 1 root root 9 Feb 15 23:38 xx04
-rw-r--r-- 1 root root 3 Feb 15 23:38 xx05
$ more xx*
$ rm -rf xx*

# /REGEXP/正则匹配
$ more a
a
b
c
123
abc
a
b
c
abc
# 匹配到了4次b
$ grep b a
b
abc
b
abc
# /REGEXP/正则匹配,{3}再重复匹配3次,总共匹配4次,分割为5个文件
$ csplit a /b/ {3}
2
8
6
4
4
$ ls xx*
xx00 xx01 xx02 xx03 xx04
$ more xx*
$ rm -rf xx*
# 匹配以b开头的有2行
$ grep -E "^b" a
b
b
# 正则匹配以b开头的行,并多次匹配,匹配到2次,分割为3个文件
$ csplit a /^b/ {*}
2
14
8
$ ls xx*
xx00 xx01 xx02
$ more xx*
# 等同于上面的命令,正则匹配1次,重复匹配1次,共2次
$ csplit a /^b/ {1}
2
14
8
$ rm -rf xx*
# /REGEXP/[OFFSET]表示正则匹配+定位行双重条件匹配,如下表示以b开头的行的后2行作为分界点
$ csplit a /^b/+2
6
18
$ ls xx*
xx00 xx01
$ more xx*
::::::::::::::
xx00
::::::::::::::
a
b
c
::::::::::::::
xx01
::::::::::::::
123
abc
a
b
c
abc
# 正则匹配以c开头的行的前2行作为分界点,可以看到生成了一个0字节的空文件
$ csplit a /^c/-2
0
24
$ rm -rf xx*
# -z删除生成的空文件
$ csplit -z a /^c/-2
24
$ ll xx*
-rw-r--r-- 1 root root 24 Feb 16 00:39 xx00
$ more xx*
$ rm -rf xx*
# 使用/REGEXP/正则匹配会以匹配到的行作为分界点分割文件
$ csplit a /abc/
10
14
$ more xx*
::::::::::::::
xx00
::::::::::::::
a
b
c
123
::::::::::::::
xx01
::::::::::::::
abc
a
b
c
abc
$ rm -rf xx*
# 使用%REGEXP%正则匹配则不包括匹配行之前的内容,即保存匹配行之后的内容到分割文件中
$ csplit a %abc%
14
$ ls xx*
xx00
# 如下分割文件的第1行显示为abc
$ more xx00
abc
a
b
c
abc
$ rm -rf xx*
$ csplit a %c%
20
# 如下分割文件的第1行显示为c
$ more xx00
c
123
abc
a
b
c
abc
$ rm -rf xx*

# --suppress-matched不显示分割行
# 默认会将分割行显示在下一个文件中,如下xx01文件的第一行显示为2
$ seq 1 5 > b
$ csplit b 2
2
8
$ ls xx*
xx00 xx01
$ more xx*
::::::::::::::
xx00
::::::::::::::
1
::::::::::::::
xx01
::::::::::::::
2
3
4
5
$ rm -rf xx*
# 添加如下选项则分割文件中不显示分割行的内容,如下xx01文件的第一行显示为3
$ csplit --suppress-matched b 2
2
6
$ ls xx*
xx00 xx01
$ more xx*
::::::::::::::
xx00
::::::::::::::
1
::::::::::::::
xx01
::::::::::::::
3
4
5
$ rm -rf xx*
# 经测试该选项不支持正则匹配中的分割行隐藏,如下xx01文件中依然显示2
$ csplit --suppress-matched b /2/
2
8
$ more xx*
::::::::::::::
xx00
::::::::::::::
1
::::::::::::::
xx01
::::::::::::::
2
3
4
5