15个适用于Linux或者Unix的有用的csplit和split命令示例
在本文中,我们将讨论Linux/Unix变体中使用的split command
和csplit command
。
这是Linux和Unix变体中可用的两种不同工具,可用于根据各种情况拆分和合并文件。
我们将通过示例介绍这些场景,这些示例使用split命令和csplit命令将文件分为多个小部分。
1.基于正则表达式匹配的csplit
我们可以基于正则表达式匹配来拆分文件。
下面有一个示例文件:
# cat my_file <report> <bundle> <name>Value 2016</name> <version>2016.03</version> </bundle> </report> <report> <bundle> <name>Value 2019</name> <version>2019.03</version> </bundle> </report> <report> <bundle> <name>Value 2017</name> <version>2017.03</version> </bundle> </report>
在此csplit命令示例中,我想基于以<report开始并以>结尾的字符串拆分文件,因此 <report>
和 </report>
之间的每个块都位于一个单独的文件中。
# csplit my_file '/^<report>$/' '{*}' 109 109 111
其中
my_file => input file /^<report>$/ => pattern match every `<report>` line {*} => repeat the previous pattern as many times as possible
如我们所见,csplit命令根据正则表达式匹配将csplit执行为三个部分:
# ls -l total 16 -rw-r--r--. 1 root root 329 Nov 7 12:34 my_file -rw-r--r--. 1 root root 109 Nov 7 12:38 xx00 -rw-r--r--. 1 root root 109 Nov 7 12:38 xx01 -rw-r--r--. 1 root root 111 Nov 7 12:38 xx02
要验证,我们可以检查任何一个分割文件的内容:
# cat xx01 <report> <bundle> <name>Value 2019</name> <version>2019.03</version> </bundle> </report>
让我们再来看一个csplit
命令示例,以基于正则表达式匹配进行csplit。
下面是具有一些功能的另一个示例文件:
# cat my_file function main1 { echo "function main1" } function main2 { echo "function main2" } function main3 { echo "function main3" }
我想将每个功能分解为单独的文件。
但是如我们所见,每个函数后面都有一个空行,因此我们需要添加一些偏移值:我将使用}作为模式
# csplit --elide-empty-files my_file '/^}/+2' "{*}" 43 43 43
其中
/^}/+2 => Check for regex matching and starting with "}". Then add +2 offset to also cut the empty line {*} => repeat the previous pattern as many times as possible
验证以下文件的内容:
# cat xx00 function main1 { echo "function main1" }
2.基于模式匹配的csplit
与正则表达式匹配类似,我们也可以基于模式匹配进行csplit。
下面是一个带有一些内容的示例文件:
# cat my_file 12345 asdfg vbn 000 4634 fghvva 000 ceqdcad 433214 000
在此csplit命令示例中,我想基于模式匹配进行拆分,其中000为模式。
因此,要基于模式进行csplit并包括行匹配模式,请添加一个+1偏移量:
# csplit --elide-empty-files my_file '/000/+1' {*} 20 16 19
其中我们在拆分后创建了三个小文件,请检查其中一个文件的内容:
# cat xx01 4634 fghvva 000
其中
{*} => Repeat argument until input is exhausted /000/+1 => Match 000 pattern and add +1 offset so 000 is added to the next split file
3.在Linux或者Unix中使用csplit取消匹配的内容
使用csplit命令,我们还可以隐藏匹配的内容(模式/字符串/正则表达式)。
在上面的csplit命令示例中,我们将取消匹配的模式,即000
# csplit --suppress-matched --elide-empty-files my_file '/000/' {*} 16 12 15
检查任何文件的内容:
# cat xx00 12345 asdfg vbn
4.使用csplit和split命令删除空文件
使用csplit或者split命令拆分文件时,拆分后可能还会得到空文件。
为了避免这种情况,我们可以使用--elide-empty-files
,如下面的csplit命令示例所示:
# csplit my_file '/000/+1' {*} 20 16 19 0
如我们所见,这里的第四个文件为0字节(空)。
因此,使用--elide-empty-files重新运行命令。
# csplit --elide-empty-files my_file '/000/+1' {*} 20 16 19
5.使用csplit命令添加前缀
在下面的示例中,我们使用--prefix来为分割后创建的所有文件添加前缀subfile_:
# csplit --elide-empty-files --prefix subfile_ my_file '/000/' {*} 16 16 19 4
检查拆分后创建的文件名带有前缀subfile_
# ls -l total 20 -rw-r--r--. 1 root root 55 Nov 7 20:08 my_file -rw-r--r--. 1 root root 16 Nov 7 21:58 subfile_00 -rw-r--r--. 1 root root 16 Nov 7 21:58 subfile_01 -rw-r--r--. 1 root root 19 Nov 7 21:58 subfile_02 -rw-r--r--. 1 root root 4 Nov 7 21:58 subfile_03
6.多个模式之间的csplit内容
在较早的csplit命令示例中,我们基于模式匹配进行csplit,但是我们也可以在多个模式之间csplit内容。
例如,我们有一个具有不同标题的文件,我们希望将每个标题之间的内容分成单独的部分。
这是我的示例文件
# cat my_file title1 content1 title2 content2 title3 content3
我们提供了我们希望为其复制标题的所有标题模式:
# csplit --elide-empty-files --prefix parts my_file '/title1/' '/title2/' '/title3/' 16 16 16
检查拆分后创建的文件的内容:
# cat parts01 title2 content2 # cat parts00 title1 content1
此命令从文件读取并创建这些长度不同的子文件:
parts00 => Text in my_file before “title2” parts01 => Text starting at “title2” and ending just before “title3” parts02 => Text starting at “title3” to the end of the file {*} => repeat the previous pattern as many times as possible
7. csplit添加后缀
默认情况下,csplit使用自定义语法拆分后创建文件。
但是我们可以添加自定义前缀,但随后还可以添加自定义后缀。
在下面的csplit命令示例中,我们为分割后创建的所有文件添加后缀.sh:
# csplit --elide-empty-files --prefix=subfile --suffix-format="%d.sh" my_file '/000/' "{*}" 16 16 19 4
其中
--prefix => Add prefix before the start of all the files created after split --suffix => Add sufix at the end of all the files created after split
分割后验证文件:
# ls -l total 20 -rw-r--r--. 1 root root 55 Nov 7 14:49 my_file -rw-r--r--. 1 root root 16 Nov 7 14:49 subfile0.sh -rw-r--r--. 1 root root 16 Nov 7 14:49 subfile1.sh -rw-r--r--. 1 root root 19 Nov 7 14:49 subfile2.sh -rw-r--r--. 1 root root 4 Nov 7 14:49 subfile3.sh
在后缀中添加更多数字的更多示例:
# csplit --elide-empty-files --prefix=subfile --suffix-format="%02d.sh" my_file '/000/' "{*}" 16 16 19 4
现在我们的后缀包含其他数字,我们可以在下面检查:
# ls -l total 20 -rw-r--r--. 1 root root 55 Nov 7 14:49 my_file -rw-r--r--. 1 root root 16 Nov 7 14:51 subfile00.sh -rw-r--r--. 1 root root 16 Nov 7 14:51 subfile01.sh -rw-r--r--. 1 root root 19 Nov 7 14:51 subfile02.sh -rw-r--r--. 1 root root 4 Nov 7 14:51 subfile03.sh
8.根据模式匹配将文件拆分为特定数量
使用split命令,我们可以将文件分割为特定数量,但稍后我们会介绍。
其中使用csplit命令,我们将基于模式匹配进行拆分,但我们还定义了必须在文件中检查模式以进行拆分的次数。
以下是我的示例文件:
# cat my_file #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
我想使用模式000进行分割,但我只想搜索一次该模式,即创建两个分割文件
# csplit --elide-empty-files --digits 1 my_file //'/000/+1' {0} 60 122
我们使用了" {0}",这意味着不重复模式匹配,因此我们仅搜索模式一次并创建分割文件。
类似地,要搜索模式两次并创建三个拆分文件,请使用以下命令:
# csplit --elide-empty-files --digits 1 my_file //'/000/+1' {1} 60 62 60
9.根据行号拆分文件
split实用程序将其输入分为1,000行,分别命名为xaa,xab,xac等,并根据行号拆分文件。
最后一节可能更短。
选项可以更改节的大小和名称的长度。
以下是我的示例文件,其中有6行:
# cat my_file #1 before first pattern #2 before first pattern #3 before second pattern #4 before second pattern #5 before third pattern #6 before third pattern
我希望基于行号分割文件,并且在此文件中每5行之后分割一次,因此我们分割后的所有文件都将包含5行
# split --lines 5 my_file
分割后验证文件
# ls -l total 12 -rw-r--r--. 1 root root 146 Nov 7 19:03 file -rw-r--r--. 1 root root 122 Nov 7 19:04 xaa -rw-r--r--. 1 root root 24 Nov 7 19:04 xab
不出所料,我的第一个文件中有5行:
# cat xaa #1 before first pattern #2 before first pattern #3 before second pattern #4 before second pattern #5 before third pattern
10.根据大小分割文件
接下来,我们将根据大小拆分文件。
我们可以使用split命令根据不同的文件大小进行拆分
使用,
K => KiloBytes M => megaBytes G => GigaBytes
在此分割命令示例中,我将基于大小每1 MB分割文件
# split --bytes 1M my_file
验证文件:
# ls -l total 6040 -rw-r--r--. 1 root root 3092035 Nov 7 19:24 my_file -rw-r--r--. 1 root root 1048576 Nov 7 19:24 xaa -rw-r--r--. 1 root root 1048576 Nov 7 19:24 xab -rw-r--r--. 1 root root 994883 Nov 7 19:24 xac
11.使用split命令添加后缀或者扩展名
前面我们展示了csplit命令示例来添加后缀或者扩展名,现在也可以通过使用--additional-suffix
的split命令来进行相同操作,如下所示:
# split --additional-suffix ".ext" -b 1M file
接下来验证带有后缀扩展名的文件
# ls -l total 6080 -rw-r--r--. 1 root root 3109034 Nov 7 19:48 file -rw-r--r--. 1 root root 1048576 Nov 7 19:55 xaa.ext -rw-r--r--. 1 root root 1048576 Nov 7 19:55 xab.ext -rw-r--r--. 1 root root 1011882 Nov 7 19:55 xac.ext
12.添加数字后缀,然后再添加其他后缀
现在,除了带有添加后缀的扩展名外,我们还可以使用--numeric-suffixes添加数字后缀。
# split --numeric-suffixes --additional-suffix ".ext" -b 1M file
接下来验证其他后缀
# ls -l total 9120 -rw-r--r--. 1 root root 3109034 Nov 7 19:48 my_file -rw-r--r--. 1 root root 1048576 Nov 7 20:00 x00.ext -rw-r--r--. 1 root root 1048576 Nov 7 20:00 x01.ext -rw-r--r--. 1 root root 1011882 Nov 7 20:00 x02.ext
13.使用split命令添加前缀
在较早的csplit命令示例中,我共享了使用csplit添加前缀的语法,并使用split命令执行了相同的操作:
在示例中,我们在分割后的每个文件的开头添加了前缀_prefix。
# split my_file prefix_
验证文件名:
# ls -l total 6096 -rw-r--r--. 1 root root 3109034 Nov 7 19:48 my_file -rw-r--r--. 1 root root 220073 Nov 7 20:05 prefix_aa -rw-r--r--. 1 root root 221369 Nov 7 20:05 prefix_ab -rw-r--r--. 1 root root 200474 Nov 7 20:05 prefix_ac
14.根据具体数量划分
现在,我们使用csplit将模式匹配后的文件拆分为特定计数,但是使用split时,我们不匹配模式,但是我们可以定义拆分后要创建的文件数。
其中我们想将" my_file"分为三部分
# split --number 3 my_file
验证相同:
# ls -l total 6088 -rw-r--r--. 1 root root 3109034 Nov 7 19:48 my_file -rw-r--r--. 1 root root 1036344 Nov 7 20:06 xaa -rw-r--r--. 1 root root 1036344 Nov 7 20:06 xab -rw-r--r--. 1 root root 1036346 Nov 7 20:06 xac
15.加入我们之前拆分过的文件
我们可以再次使用以下语法将已拆分的所有文件合并或者合并为一个文件
# cat split-files-* > your_new_filename
我们之前已经分割了一些文件,所以我将使用此方法再次组合所有分割的文件以创建一个新文件。
# cat xa* > my_new_file
现在,我们可以验证新文件的内容:
# cat my_new_file #1 before first pattern #2 before first pattern #3 before second pattern #4 before second pattern #5 before third pattern #6 before third pattern