Linux筆記之如何分割文件或管道流:split

 

1、簡介

在Linux中合併文件可使用cat命令,後面跟上要合併的文件而後重定向到一個新的文件中便可,甚至能夠追加合併。但若是要將一個大文件分割爲多個小文件應該如何操做呢?html

在Linux的coreutils中有一個工具split實現了這個功能,能夠把一個大文件切割爲多個小文件,甚至能夠藉助管道將流切成固定大小的文件,切割規則可使用行數,也可使用字節數。python

 

2、預備測試數據

先生成一個稍微大點的文件,接下來就切割這個文件:ruby

#! /bin/bash

for((i=0;i<1000000;i++));
do
	echo $i >> data
done

將上面這段保存爲gen-data.sh,而後執行生成一個名爲data有1000000行的文本文件。bash

 

3、按行數分割

將data按照每10000行爲一個文件切割:工具

image

對於切割後的小文件的命名,名稱由「前綴」+「後綴」的形式組成,全部的小文件擁有相同的前綴,前綴是爲了將它們歸爲一類,默認的前綴爲x,後綴是一個自增的序列,即給每一個小文件編號,默認從aa開始遞增編號。測試

自定義前綴和後綴,-d表示使用數字後綴:htm

image

上面的自增好像有點bug,由於默認的後綴長度爲2而生成的文件數位數超出了2,因此後面的部分計數看起來就有點奇怪,能夠指定後綴長度修正它:blog

image

如今編號沒有問題了。ip

 

4、按字節分割

還能夠對文件按照字節數進行分割,通常用於二進制文件,這裏爲了方便直接拿data文件作分割了:it

image 

 

5、從標準輸入讀入

通常說的從標準輸入讀取實際的應用場景通常都是從管道中讀入,因此能夠假設一個場景,有一個程序隨機的輸出一些信息到標準輸出, 如今想每100000行存爲一個文件方便後續操做,如何作比較方便呢?

通常狀況下可能會使用一些腳本語言作這個每n行切換一個文件的操做,但這種屁大點事就要引入一個python或ruby之類的真是浪費,使用split一行就能夠搞定。

將前面的gen-data.sh複製爲gen-data-to-stdout.sh改成直接輸出到標準輸出:

#! /bin/bash

while true
do
	echo $i
done

如今有了一個會不斷輸出信息的程序,接下來使用split實現每n行輸出一個新文件的功能:

./gen-data-to-stdout.sh | split -l 100000 -d -a 10 - foo-stdout-

而後查看當前文件夾下的輸出:

image 

上面是一個對管道流按照行數分割的例子,接下來看一個對管道流按照字節數分割的例子,對tar打包後的文件按照2g爲單位進行分割:

tar zcvf - foo-stdout-* | split -b 2G -d -a 3 - foo-stdout.tar.gz.

 

6、思考:爲何分割爲的小文件須要前綴呢?

默認狀況下分割後的小文件放在當前文件夾下,不會自動建立新的文件夾來存放它們(想想建立文件夾的目的是什麼呢),前綴的目的就是爲了提供一種方式可以方便的找到分割後的小文件以對其進行批量操做,好比對data文件進行分割操做,分割爲了data-part-000、data-part-00一、data-part-00二、data-part-003 ...等一千個小文件,那麼可使用前綴data-part-*對這一千個小文件進行批量操做,即便當前目錄下還有徹底無關的千八百個其它文件也對這個操做不影響,只要前綴不衝突就行。若是沒有前綴的話分割後的這一千個小文件就跟其它的文件混在一塊兒了,要批量操做它們很困難。

總結:對分割爲的小文件加相同的前綴是爲了方便找到它們,實際上能夠將前綴看作是一個組名稱,使用組前綴將這些小文件打成一組。

 

7、總結

使用split能夠將一個大文件分割爲多個小文件,分割方式可使用字節或行數,也能夠從管道中讀入數據流對數據流按照行數或字節數分割。

 

.

相關文章
相關標籤/搜索