splitコマンドは、標準出力やファイルを受け付けて指定された行数などでファイルに分割してくれるコマンドだ。 ファイルが大きすぎる場合や決まった行数ごとに内容が別れているファイルを分割して別のファイルにしたり、分割した内容ごとにコマンドを実行させたりすることができる。

1. 基本的な使い方

基本的には、以下のように標準入力やファイルを指定して分割をする。

command | split
split ファイルPATH
blacknon@BS-PUB-DEVELOP:~/test_split$ cat test.list
a01 a02 a03 a04 a05 a06 a07 a08 a09 a10
b01 b02 b03 b04 b05 b06 b07 b08 b09 b10
c01 c02 c03 c04 c05 c06 c07 c08 c09 c10
d01 d02 d03 d04 d05 d06 d07 d08 d09 d10
e01 e02 e03 e04 e05 e06 e07 e08 e09 e10
f01 f02 f03 f04 f05 f06 f07 f08 f09 f10
g01 g02 g03 g04 g05 g06 g07 g08 g09 g10
h01 h02 h03 h04 h05 h06 h07 h08 h09 h10
i01 i02 i03 i04 i05 i06 i07 i08 i09 i10
j01 j02 j03 j04 j05 j06 j07 j08 j09 j10
k01 k02 k03 k04 k05 k06 k07 k08 k09 k10
l01 l02 l03 l04 l05 l06 l07 l08 l09 l10
m01 m02 m03 m04 m05 m06 m07 m08 m09 m10
n01 n02 n03 n04 n05 n06 n07 n08 n09 n10
o01 o02 o03 o04 o05 o06 o07 o08 o09 o10
p01 p02 p03 p04 p05 p06 p07 p08 p09 p10
q01 q02 q03 q04 q05 q06 q07 q08 q09 q10
r01 r02 r03 r04 r05 r06 r07 r08 r09 r10
s01 s02 s03 s04 s05 s06 s07 s08 s09 s10
t01 t02 t03 t04 t05 t06 t07 t08 t09 t10
u01 u02 u03 u04 u05 u06 u07 u08 u09 u10
v01 v02 v03 v04 v05 v06 v07 v08 v09 v10
w01 w02 w03 w04 w05 w06 w07 w08 w09 w10
x01 x02 x03 x04 x05 x06 x07 x08 x09 x10
y01 y02 y03 y04 y05 y06 y07 y08 y09 y10
z01 z02 z03 z04 z05 z06 z07 z08 z09 z10
blacknon@BS-PUB-DEVELOP:~/test_split$ # 5行ごとに分割してやる
blacknon@BS-PUB-DEVELOP:~/test_split$ cat test.list | split -l 5
blacknon@BS-PUB-DEVELOP:~/test_split$ ls -la
合計 36
drwxrwxr-x  2 blacknon blacknon 4096  7月 29 13:40 .
drwxr-xr-x 40 blacknon blacknon 4096  7月 29 13:39 ..
-rw-rw-r--  1 blacknon blacknon 1040  7月 29 13:39 test.list
-rw-rw-r--  1 blacknon blacknon  200  7月 29 13:40 xaa
-rw-rw-r--  1 blacknon blacknon  200  7月 29 13:40 xab
-rw-rw-r--  1 blacknon blacknon  200  7月 29 13:40 xac
-rw-rw-r--  1 blacknon blacknon  200  7月 29 13:40 xad
-rw-rw-r--  1 blacknon blacknon  200  7月 29 13:40 xae
-rw-rw-r--  1 blacknon blacknon   40  7月 29 13:40 xaf
blacknon@BS-PUB-DEVELOP:~/test_split$ grep '' xa*
xaa:a01 a02 a03 a04 a05 a06 a07 a08 a09 a10
xaa:b01 b02 b03 b04 b05 b06 b07 b08 b09 b10
xaa:c01 c02 c03 c04 c05 c06 c07 c08 c09 c10
xaa:d01 d02 d03 d04 d05 d06 d07 d08 d09 d10
xaa:e01 e02 e03 e04 e05 e06 e07 e08 e09 e10
xab:f01 f02 f03 f04 f05 f06 f07 f08 f09 f10
xab:g01 g02 g03 g04 g05 g06 g07 g08 g09 g10
xab:h01 h02 h03 h04 h05 h06 h07 h08 h09 h10
xab:i01 i02 i03 i04 i05 i06 i07 i08 i09 i10
xab:j01 j02 j03 j04 j05 j06 j07 j08 j09 j10
xac:k01 k02 k03 k04 k05 k06 k07 k08 k09 k10
xac:l01 l02 l03 l04 l05 l06 l07 l08 l09 l10
xac:m01 m02 m03 m04 m05 m06 m07 m08 m09 m10
xac:n01 n02 n03 n04 n05 n06 n07 n08 n09 n10
xac:o01 o02 o03 o04 o05 o06 o07 o08 o09 o10
xad:p01 p02 p03 p04 p05 p06 p07 p08 p09 p10
xad:q01 q02 q03 q04 q05 q06 q07 q08 q09 q10
xad:r01 r02 r03 r04 r05 r06 r07 r08 r09 r10
xad:s01 s02 s03 s04 s05 s06 s07 s08 s09 s10
xad:t01 t02 t03 t04 t05 t06 t07 t08 t09 t10
xae:u01 u02 u03 u04 u05 u06 u07 u08 u09 u10
xae:v01 v02 v03 v04 v05 v06 v07 v08 v09 v10
xae:w01 w02 w03 w04 w05 w06 w07 w08 w09 w10
xae:x01 x02 x03 x04 x05 x06 x07 x08 x09 x10
xae:y01 y02 y03 y04 y05 y06 y07 y08 y09 y10
xaf:z01 z02 z03 z04 z05 z06 z07 z08 z09 z10

デフォルトでは「x~(aからはじまるアルファベット2桁)」というファイル名で分割されるのだが、引数の最後に分割後のファイル名を指定することもできる(標準入力から受け取っている場合、ファイル名を指定する箇所に「-」を指定してやる)。

command | split - 分割後のベースファイル名
split ファイルPATH 分割後のベースファイル名
blacknon@BS-PUB-DEVELOP:~/test_split$ ls -la
合計 12
drwxrwxr-x  2 blacknon blacknon 4096  7月 29 16:55 .
drwxr-xr-x 40 blacknon blacknon 4096  7月 29 13:39 ..
-rw-rw-r--  1 blacknon blacknon 1040  7月 29 16:55 test.list
blacknon@BS-PUB-DEVELOP:~/test_split$ cat test.list | split -l 5 - x_test_
blacknon@BS-PUB-DEVELOP:~/test_split$ ls -la
合計 36
drwxrwxr-x  2 blacknon blacknon 4096  7月 29 17:45 .
drwxr-xr-x 40 blacknon blacknon 4096  7月 29 13:39 ..
-rw-rw-r--  1 blacknon blacknon 1040  7月 29 16:55 test.list
-rw-rw-r--  1 blacknon blacknon  200  7月 29 17:45 x_test_aa
-rw-rw-r--  1 blacknon blacknon  200  7月 29 17:45 x_test_ab
-rw-rw-r--  1 blacknon blacknon  200  7月 29 17:45 x_test_ac
-rw-rw-r--  1 blacknon blacknon  200  7月 29 17:45 x_test_ad
-rw-rw-r--  1 blacknon blacknon  200  7月 29 17:45 x_test_ae
-rw-rw-r--  1 blacknon blacknon   40  7月 29 17:45 x_test_af

分割後のベースファイル名に付与する「aa~zz」の値を数字にする場合は、「-d」オプションを付与する。 (なお、開始番号を指定したい場合は「--numeric-suffixes=開始番号」で指定を、桁数を指定する場合は「--suffix-length=桁数」で指定できる。 さらに分割後の末尾にサフィックスを付与したい場合は、--additional-suffix=文字列で指定可能。)

blacknon@BS-PUB-DEVELOP:~/test_split$ cat test.list | split -l 5 -d - x_test_
blacknon@BS-PUB-DEVELOP:~/test_split$ ls -la
合計 292
drwxrwxr-x  2 blacknon blacknon 266240  7月 29 17:59 .
drwxr-xr-x 40 blacknon blacknon   4096  7月 29 13:39 ..
-rw-rw-r--  1 blacknon blacknon   1040  7月 29 16:55 test.list
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_00
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_01
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_02
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_03
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_04
-rw-rw-r--  1 blacknon blacknon     40  7月 29 17:59 x_test_05
blacknon@BS-PUB-DEVELOP:~/test_split$
blacknon@BS-PUB-DEVELOP:~/test_split$ cat test.list | split -l 5 --suffix-length=5 --additional-suffix=.list -d - x_test_
blacknon@BS-PUB-DEVELOP:~/test_split$ ls -la
合計 316
drwxrwxr-x  2 blacknon blacknon 266240  7月 29 17:59 .
drwxr-xr-x 40 blacknon blacknon   4096  7月 29 13:39 ..
-rw-rw-r--  1 blacknon blacknon   1040  7月 29 16:55 test.list
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_00
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_00000.list
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_00001.list
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_00002.list
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_00003.list
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_00004.list
-rw-rw-r--  1 blacknon blacknon     40  7月 29 17:59 x_test_00005.list
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_01
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_02
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_03
-rw-rw-r--  1 blacknon blacknon    200  7月 29 17:59 x_test_04
-rw-rw-r--  1 blacknon blacknon     40  7月 29 17:59 x_test_05

2. 分割の基準(行数やバイト数、分割する数)を指定する

行数やバイト数、分割数などを指定する場合は、それぞれ以下のオプションを指定する

  • 行数で分割する場合 … -l N(行数)
  • バイト数で分割する場合 … -b N(バイト数)
  • 分割する数を指定する場合 … -n N(分割する数) ※ 標準入力からだとファイルサイズが計算できずエラーになる

ちなみに、分割数を指定するnオプションについては、以下のような指定も可能だ。

  • -n N … ファイルサイズに基づいてN個に分割する
  • -n K/N … 分割したN個のうち、K個目を標準出力する
  • -n l/N … N個のファイルに分割しても、行やレコードの分割は行わない
  • -n l/K/N … N個のファイルに分割しても、行やレコードの分割は行わずにK番目を標準出力する
  • -n l/N … N個のファイルに分割する際、行やレコードをラウンドロビンする
  • -n l/N … N個のファイルに分割する際、行やレコードをラウンドロビンしてK番目を標準出力する

3. 分割結果をファイルに出力せず、そのままコマンドに渡して処理させる

GNU拡張されたsplitコマンドの場合、--filterオプションで分割した内容に対し個別にコマンドを実行させることが可能になる。 指定できるコマンド内ではプロセス置換もパイプも使えるので、かなり応用が効く様子。個人的にかなりお気に入りの機能だ。

command | split --filter="コマンド"
split --filter="コマンド" file
blacknon@BS-PUB-DEVELOP:~/test_split$ cat test.list
a01 a02 a03 a04 a05 a06 a07 a08 a09 a10
b01 b02 b03 b04 b05 b06 b07 b08 b09 b10
c01 c02 c03 c04 c05 c06 c07 c08 c09 c10
d01 d02 d03 d04 d05 d06 d07 d08 d09 d10
e01 e02 e03 e04 e05 e06 e07 e08 e09 e10
f01 f02 f03 f04 f05 f06 f07 f08 f09 f10
g01 g02 g03 g04 g05 g06 g07 g08 g09 g10
h01 h02 h03 h04 h05 h06 h07 h08 h09 h10
i01 i02 i03 i04 i05 i06 i07 i08 i09 i10
j01 j02 j03 j04 j05 j06 j07 j08 j09 j10
k01 k02 k03 k04 k05 k06 k07 k08 k09 k10
l01 l02 l03 l04 l05 l06 l07 l08 l09 l10
m01 m02 m03 m04 m05 m06 m07 m08 m09 m10
n01 n02 n03 n04 n05 n06 n07 n08 n09 n10
o01 o02 o03 o04 o05 o06 o07 o08 o09 o10
p01 p02 p03 p04 p05 p06 p07 p08 p09 p10
q01 q02 q03 q04 q05 q06 q07 q08 q09 q10
r01 r02 r03 r04 r05 r06 r07 r08 r09 r10
s01 s02 s03 s04 s05 s06 s07 s08 s09 s10
t01 t02 t03 t04 t05 t06 t07 t08 t09 t10
u01 u02 u03 u04 u05 u06 u07 u08 u09 u10
v01 v02 v03 v04 v05 v06 v07 v08 v09 v10
w01 w02 w03 w04 w05 w06 w07 w08 w09 w10
x01 x02 x03 x04 x05 x06 x07 x08 x09 x10
y01 y02 y03 y04 y05 y06 y07 y08 y09 y10
z01 z02 z03 z04 z05 z06 z07 z08 z09 z10
blacknon@BS-PUB-DEVELOP:~/test_split$
blacknon@BS-PUB-DEVELOP:~/test_split$ # 各分割の1行目のみを出力させる(+echoで区切りを入れる)
blacknon@BS-PUB-DEVELOP:~/test_split$ cat test.list | split -l 5 --filter='sed -n 1p;echo =========='
a01 a02 a03 a04 a05 a06 a07 a08 a09 a10
==========
f01 f02 f03 f04 f05 f06 f07 f08 f09 f10
==========
k01 k02 k03 k04 k05 k06 k07 k08 k09 k10
==========
p01 p02 p03 p04 p05 p06 p07 p08 p09 p10
==========
u01 u02 u03 u04 u05 u06 u07 u08 u09 u10
==========
z01 z02 z03 z04 z05 z06 z07 z08 z09 z10
==========
blacknon@BS-PUB-DEVELOP:~/test_split$ cat sum.list
a0001 3536
a0002 31311
a0003 27955
b0001 22929
b0002 20045
b0003 15420
c0001 4240
c0002 25307
c0003 18504
d0001 6872
d0002 28946
d0003 23524
blacknon@BS-PUB-DEVELOP:~/test_split$ # 分割した内容ごとにトータルを計算
blacknon@BS-PUB-DEVELOP:~/test_split$ cat sum.list | split -l 3 --filter="awk '{a+=\$2;print \$0}END{print \"TOTAL\",a}';echo ---"
a0001 3536
a0002 31311
a0003 27955
TOTAL 62802
---
b0001 22929
b0002 20045
b0003 15420
TOTAL 58394
---
c0001 4240
c0002 25307
c0003 18504
TOTAL 48051
---
d0001 6872
d0002 28946
d0003 23524
TOTAL 59342
---
blacknon@BS-PUB-DEVELOP:~/test_split$ # 分割した内容ごとにパーセントを計算(見てわかるように、変数の代入をしての処理も行える)
blacknon@BS-PUB-DEVELOP:~/test_split$ cat sum.list | split -l 3 --filter="(a=\$(cat) && awk 'NR==FNR{a=a+\$2;next}{c=(\$2/a)*100;print \$1,\$2,c\"%\"}' <(echo -e \"\$a\") <(echo -e \"\$a\"));echo ======"
a0001 3536 5.63039%
a0002 31311 49.8567%
a0003 27955 44.5129%
======
b0001 22929 39.266%
b0002 20045 34.3272%
b0003 15420 26.4068%
======
c0001 4240 8.82396%
c0002 25307 52.667%
c0003 18504 38.5091%
======
d0001 6872 11.5803%
d0002 28946 48.7783%
d0003 23524 39.6414%
======

4.セパレートを指定する

通常は改行を基準としているが、-tオプションで指定した1文字をセパレートとして分割させることもできる。 以下の例では、スペースをセパレートに指定している。

blacknon@BS-PUB-DEVELOP:~/test_split$ cat test.list | split -l 3 -t' ' --filter='echo -e $(cat);echo ======' | head -20
a01 a02 a03
======
a04 a05 a06
======
a07 a08 a09
======
a10 b01 b02 b03
======
b04 b05 b06
======
b07 b08 b09
======
b10 c01 c02 c03
======
c04 c05 c06
======
c07 c08 c09
======
c10 d01 d02 d03
======