split コマンド入門 - 大きなファイルを分割・結合する

split コマンド入門 - 大きなファイルを分割・結合する

大きすぎるファイル、どうする?

リナ: せんぱい、5GB のログファイルを USB メモリに入れようとしたら「ファイルが大きすぎます」って怒られました...
ライニー先輩: それ、split コマンドの出番だね。大きなファイルを小さなかたまりに切り分けて、あとで元通りにくっつけられるんだ。一緒に見ていこう。

この記事でわかること

  • split で大きなファイルを サイズ・行数・個数 で分割する方法
  • 分割したファイルを cat元通りに結合 する方法
  • 連番サフィックス(xaa ではなく part_01)の付け方
  • 分割・結合後に ファイルが壊れていないか を確認する方法

1. split コマンドとは?

結論: split は 1 つのファイルを複数の小さなファイルに分割するコマンド。cat で連結すれば完全に元のファイルへ戻せる。

リナ: そもそも「分割」って、ファイルを壊しちゃうんじゃないですか?
ライニー先輩: 大丈夫。split はコピーを切り分けるだけで、元ファイルはそのまま残るよ。しかも切り分けた断片を順番につなげれば、1 バイトも欠けずに元に戻せる。
リナ: なるほど、安心しました。どんなときに使うんですか?
ライニー先輩: 「容量制限のあるメディアに入れたい」「巨大ファイルを少しずつ転送したい」「サイズの大きいログを扱いやすく小分けしたい」ときだね。まずは一番シンプルな形を見てみよう。

まずは練習用のファイルを用意する。

# 50MB のダミーファイルを作成
$ dd if=/dev/zero of=bigfile.dat bs=1M count=50
$ ls -lh bigfile.dat
-rw-r--r-- 1 user user 50M Jun  5 10:00 bigfile.dat

2. サイズで分割するには?

結論: split -b サイズ 元ファイル 接頭辞 でサイズ指定。-b 100M なら 100MB ごと、-b 10M なら 10MB ごとに切り分けられる。

リナ: さっそく 10MB ずつに分けてみたいです。
ライニー先輩: -b(bytes の b)を使うよ。最後の part_ は出力ファイルの名前の頭につく文字列(接頭辞)ね。
$ split -b 10M bigfile.dat part_
$ ls -lh part_*
-rw-r--r-- 1 user user 10M Jun  5 10:01 part_aa
-rw-r--r-- 1 user user 10M Jun  5 10:01 part_ab
-rw-r--r-- 1 user user 10M Jun  5 10:01 part_ac
-rw-r--r-- 1 user user 10M Jun  5 10:01 part_ad
-rw-r--r-- 1 user user 10M Jun  5 10:01 part_ae
リナ: part_aa, part_ab... ってアルファベットが増えていくんですね。
ライニー先輩: そう。接頭辞を省略すると xaa, xab... になる。サイズの単位は K(キロ)M(メガ)G(ギガ)が使えるよ。b を付けない 10M は 10×1024×1024 バイト、10MB と書くと 10×1000×1000 バイトになる点だけ覚えておくと安心。

単位の早見表

  • split -b 700M → CD 1 枚に収まるサイズ
  • split -b 100M → クラウドアップロードしやすいサイズ
  • split -b 1G → 1GB ごと

3. 行数で分割するには?

結論: テキストやログは split -l 行数 元ファイル 接頭辞 で行単位に分割できる。途中で行が切れないので CSV・ログ向き。

リナ: ログファイルを 1000 行ずつに分けたいときは?
ライニー先輩: -l(lines の l)を使う。サイズで切ると行の途中でブツッと切れちゃうけど、-l なら必ず行の区切りで分けてくれるんだ。CSV やログにはこっちが安全。
$ split -l 1000 access.log chunk_
$ wc -l chunk_*
   1000 chunk_aa
   1000 chunk_ab
    342 chunk_ac
   2342 合計

サイズ分割(-b)はバイト単位で機械的に切るため、テキストファイルだと行の途中で分断される。行の意味を保ちたいときは必ず -l を使う。

4. 個数を指定して分割するには?

結論: split -n 個数 元ファイル 接頭辞 でファイルを指定した個数に等分割できる。「ちょうど 5 個に分けたい」ときに便利。

リナ: 「10MB ずつ」じゃなくて「とにかく 5 個に分けたい」ときもありますよね。
ライニー先輩: そのときは -n(number の n)。ファイル全体を 5 等分してくれる。サイズを計算しなくていいのが楽だね。
$ split -n 5 bigfile.dat group_
$ ls -lh group_*
-rw-r--r-- 1 user user 10M Jun  5 10:05 group_aa
-rw-r--r-- 1 user user 10M Jun  5 10:05 group_ab
-rw-r--r-- 1 user user 10M Jun  5 10:05 group_ac
-rw-r--r-- 1 user user 10M Jun  5 10:05 group_ad
-rw-r--r-- 1 user user 10M Jun  5 10:05 group_ae

5. 分割したファイルを元に戻すには?

結論: 結合には専用コマンドは不要。cat 接頭辞* > 復元ファイル で順番どおり連結すれば元のファイルへ戻る。

リナ: 分けたのはいいけど、どうやって元に戻すんですか?「join コマンド」とかあります?
ライニー先輩: いい質問。join という別コマンドもあるけど、それは表の結合用で別物。split で分けた断片を戻すには cat を使うんだ。
リナ: えっ、ファイルを表示する cat で?
ライニー先輩: そう。cat は複数ファイルを順番につなげて出力するコマンドでもあるからね。> でファイルに書き出せば結合完了。
$ cat part_* > restored.dat
$ ls -lh restored.dat
-rw-r--r-- 1 user user 50M Jun  5 10:10 restored.dat

並び順に注意cat part_* のワイルドカード(*)はアルファベット順に展開されるため part_aapart_ab → ... と正しい順序になる。ただし part_1, part_2, ... part_10 のような数字サフィックスを自分で付けた場合、part_10part_2 より先に並んでしまうことがある。次の章のゼロ埋め連番を使えば安全。

6. 連番のサフィックスを付けるには?

結論: -d で数字サフィックス(00, 01...)になり、-a で桁数を指定できる。--additional-suffix で拡張子も付けられる。

リナ: aa, ab じゃなくて 01, 02 みたいな数字の方が分かりやすいです。
ライニー先輩: -d(digits の d)を付けると数字になるよ。桁数は -a で指定。さらに --additional-suffix.part みたいな拡張子も付けられる。
$ split -b 10M -d -a 2 --additional-suffix=.part bigfile.dat backup_
$ ls backup_*
backup_00.part  backup_01.part  backup_02.part  backup_03.part  backup_04.part

ゼロ埋め連番(00, 01, ... 10, 11)なら cat backup_*.part > restored.dat で常に正しい順序で結合できる。100 個を超えそうなときは -a 3 で 3 桁にしておくと安心。

7. ファイルが壊れていないか確認するには?

結論: 分割・結合の前後で sha256sum のハッシュ値を比べる。値が一致すれば 1 バイトも欠けずに復元できている証拠。

リナ: 結合したファイル、本当に元と同じか不安です...
ライニー先輩: そこで sha256sum。ファイルの中身から計算される「指紋」みたいな値だよ。元ファイルと復元ファイルで指紋が一致すれば完全に同じ。転送やコピーの途中で壊れていないかも確認できる。
$ sha256sum bigfile.dat restored.dat
e3b0c44298fc1c149afbf4c8996fb924...  bigfile.dat
e3b0c44298fc1c149afbf4c8996fb924...  restored.dat
リナ: 左側の長い文字列が同じ!これで安心です。
ライニー先輩: 違っていたら、結合の順番が間違っているか、転送中に壊れたサイン。そのときは分割からやり直そう。
ミニ課題(クリックで開く)

practice.dat という 30MB のファイルを作り、(1) 7MB ごとに分割、(2) cat で結合、(3) 元ファイルとハッシュが一致することを確認してみよう。

ヒント: dd if=/dev/zero of=practice.dat bs=1M count=30 でファイルを作成 → split -b 7M practice.dat p_cat p_* > joined.datsha256sum practice.dat joined.dat

8. よくあるつまずきと対処

結論: つまずきの大半は「結合順序」「サイズ単位の勘違い」「ディスク容量不足」の 3 つ。分割前に容量と単位を確認する。

症状 原因 対処
結合したら中身が壊れている 結合順序が違う -d のゼロ埋め連番にして cat ...*
想定よりファイル数が多い/少ない M(1024 系)と MB(1000 系) 単位を統一する
No space left on device 分割で実質 2 倍の容量が必要 先に df -h で空きを確認
テキストの行が途中で切れる -b(バイト)で切った -l(行)で分割し直す

やってはいけないこと

  • 元ファイルを消す前に結合テストをしていない
  • ハッシュ値の確認をしていない
  • 空き容量を確認せずに分割を始める

まとめ / 次に読む