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

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

この記事でできるようになること

  • `split` でサイズ・行数・個数を指定してファイルを分割できる
  • `cat 接頭辞* > 復元ファイル` で分割前のファイルに戻せる
  • `sha256sum` で復元したファイルが壊れていないか確かめられる

前提知識(先に読むと理解しやすい記事)

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

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

言葉の整理(先に取りちがえを防ぎます)

  • 分割:1 つのファイルを複数の小さなファイルに切り分けることです。元のファイルは残ります。
  • 結合:切り分けたファイルを順番につないで、元の 1 つに戻すことです。
  • 接頭辞:作られるファイル名の先頭に付く文字列です。「プレフィックス」も同じものを指します。
  • サフィックス:ファイル名の末尾に付く文字です。part_aaaa がそれにあたります。
  • ハッシュ値:ファイルの中身から計算される、指紋のような文字列です。「チェックサム」もほぼ同じ意味で使われます。

この記事でわかること

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

1. split コマンドとは?

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

リナ: そもそも分割すると、ファイルが壊れてしまわないでしょうか。
ライニー先輩: 大丈夫。split は中身を読んで別のファイルに書き出すだけなんだ。元のファイルはそのまま残るよ。
ライニー先輩: しかも切り分けたものを順番につなげれば、1 バイトも欠けずに元に戻せる。
リナ: それなら安心しました。どんなときに使うのですか。
ライニー先輩: 容量に制限のあるメディアに入れたいときだね。大きなファイルを少しずつ転送したいときにも使う。
ライニー先輩: サイズの大きいログを、あつかいやすく小分けしたいときにも便利だよ。まずはいちばん簡単な形を見てみよう。

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

# 50MB の練習用ファイルを作る(中身は 0 が並んだだけのダミー)
$ head -c 50M /dev/zero > bigfile.dat

/dev/zero は「0 をいくらでも出してくれる特別なファイル」です。head -c 50M で先頭 50MB 分だけ取り出し、>bigfile.dat に書き出しています。

同じことを dd というコマンドで書いている記事も多くあります。dd は書き込み先を of= で指定します。

ここでは dd を使いません。of= にディスクの名前を書いてしまうと、そのディスクを直接上書きしてしまうためです。GUI のようにゴミ箱へ入ることも、確認画面が出ることもありません。パソコンが起動しなくなることもあります。

head -c なら書き込み先はふつうのファイルだけです。初心者のうちはこちらを使ってください。

$ 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、つまりバイトの頭文字だね。
ライニー先輩: 最後に書いた 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(ギガ)が使える。
ライニー先輩: 1 つだけ注意。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 なら必ず行の区切りで分けてくれるんだ。
ライニー先輩: 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、つまり個数の頭文字だね。
ライニー先輩: ファイル全体を 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

-n 5 はバイト数で 5 等分します。そのためテキストファイルでは、行のとちゅうで切れます。

行を守ったまま 5 個に分けたいときは split -n l/5 と書きます。l は line(行)の頭文字です。

$ split -n l/5 access.log group_

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_** は、名前を文字として見くらべた順に展開されます。

split が付ける aa ab ac は、けた数がそろっています。だから正しい順序になります。

いっぽう part_1, part_2, ... part_10 のような名前を自分で付けると、part_10part_2 より先に来てしまいます。次の章のゼロ埋め連番を使えば安全です。

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

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

リナ: aa, ab ではなく 01, 02 のような数字のほうがわかりやすいです。
ライニー先輩: -d を付けると数字になるよ。digits、つまりけたの頭文字だね。
ライニー先輩: けた数は -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

ゼロ埋めの連番なら、cat backup_*.part > restored.dat はいつも正しい順序で結合できます。00, 01, ... 10, 11 のように、けたがそろうからです。

100 個を超えそうなときは -a 3 を使い、3 けたにしておくと安心です。

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

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

リナ: 結合したファイルが本当に元と同じか、不安です。
ライニー先輩: そこで sha256sum を使う。ファイルの中身から計算される、指紋のような値だよ。
ライニー先輩: 元のファイルと復元したファイルで指紋が一致すれば、中身は完全に同じ。
ライニー先輩: 転送やコピーのとちゅうで壊れていないかも、これで確かめられるんだ。
$ sha256sum bigfile.dat restored.dat
9f2c7b1a4e6d8035c1af52e0b73d94e6...  bigfile.dat
9f2c7b1a4e6d8035c1af52e0b73d94e6...  restored.dat

(ハッシュ値はファイルの中身によって変わります。上の値は表示の形を示す例です)

リナ: 左側の長い文字列が同じです。これで安心しました。
ライニー先輩: もし値がちがっていたら、結合の順番がまちがっているサインだよ。転送のとちゅうで壊れた可能性もある。
ライニー先輩: そのときは分割からやり直そう。

8. リナの失敗:自分で付けた数字で順番が崩れる

結論: * は名前を文字として見くらべて展開する。けたがそろっていない数字を自分で付けると、結合の順番が崩れる。

リナ: 先輩、分けたファイルに自分で part_1 から part_10 まで名前を付けました。でも結合したら中身が壊れていました。

小さな例で、何が起きたのかを見てみます。

$ touch part_1 part_2 part_10
$ ls part_*
part_1
part_10
part_2
リナ: part_10part_2 より先に出ています。数の大きさは無視されているのですね。
ライニー先輩: そう。* は名前を 文字として左から 見くらべるんだ。12 をくらべた時点で、part_10 のほうが先だと決まる。
リナ: えっ、では cat part_* > restored.dat は、この順番でつないでしまうんですか。
ライニー先輩: そのとおり。だから中身の並びが入れかわり、復元したファイルが壊れるんだ。
リナ: 数字にしたほうがわかりやすいと思ったのに、逆に危なかったんですね。納得しました。
ライニー先輩: だから -d -a 2 を使う。part_01, part_02, part_10 とけたがそろえば、文字として見くらべても正しい順序になるよ。

split が付ける aa ab ac も、けた数がそろっています。名前を自分で変えないかぎり、順番の事故は起きません。

心配なときは、結合したあとに sha256sum で確かめてください。値が一致すれば順番も中身も正しいという証拠になります。

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

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

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

分割の前後で必ずやること

  • 元のファイルを消す前に、結合できるか試す
  • 結合したら sha256sum で元ファイルとハッシュ値をくらべる
  • 分割を始める前に df -h で空き容量を確かめる

splitsha256sum は、本サイトの仮想ターミナル入力したコマンドを解釈してコンピュータに実行させる対話プログラム。にはまだありません。この記事の例は、手元の Linux やターミナルで試してください。

元のファイルを消すのは、結合とハッシュの確認が終わってからにしてください。rm で消したファイルは、GUI とちがってゴミ箱に入りません。その場で完全に消えます。

10. ミニ課題:実際にやってみよう

結論: 行数分割・サイズ分割と結合・ハッシュ確認の 3 問で、splitcat の往復を手で確かめる。

リナ: 手順はわかりました。手を動かして確かめたいです。
ライニー先輩: いいね、3 問用意したよ。まず練習用のディレクトリファイルをまとめて整理する入れ物。Windows や macOS の「フォルダ」と同じもの。を作って、その中で試してみて。
$ mkdir -p ~/split-practice && cd ~/split-practice
$ seq 1 25 > numbers.txt

課題 1numbers.txt を 10 行ずつに分割し、できたファイルの行数を確かめよう。

ヒント 1(方向づけ)を見る

サイズではなく行の数で分けます。行の区切りを守ってくれるオプションを使います。

ヒント 2(コマンド名)を見る

使うのは splitwc です。split には行の数で分けるオプションがあります。

答えを見る
$ split -l 10 numbers.txt num_
$ wc -l num_*
10 num_aa
10 num_ab
 5 num_ac
25 合計

25 行を 10 行ずつに分けたので、最後だけ 5 行になります。

課題 2:分割したファイルを結合して joined.txt を作ろう。

ヒント 1(方向づけ)を見る

結合には専用のコマンドは要りません。複数のファイルを順につなげて出力するコマンドを使います。

ヒント 2(コマンド名)を見る

使うのは cat です。結果をファイルに書き出す記号は第 5 章で出てきました。

答えを見る
$ cat num_* > joined.txt
$ wc -l joined.txt
25 joined.txt

元と同じ 25 行に戻りました。

課題 3numbers.txtjoined.txt の中身が完全に同じか確かめよう。

ヒント 1(方向づけ)を見る

行数が同じでも、中身が同じとはかぎりません。ファイルの中身から計算される指紋をくらべます。

ヒント 2(コマンド名)を見る

使うのは sha256sum です。ファイル名は 2 つ並べて渡せます。

答えを見る
$ sha256sum numbers.txt joined.txt

左側の長い文字列が 2 行とも同じなら、中身は完全に同じです。

練習が終わったら、作ったディレクトリごと片づけられます。中身を確かめてから消してください。

$ cd ~
$ ls ~/split-practice
$ rm -r ~/split-practice

rm -r はディレクトリを中身ごと消します。実行する前に、パスファイルやディレクトリの場所を表す文字列。~/split-practice であることを必ず確かめてください。

11. 振り返り

リナ: 整理します。分けるのは split、戻すのは cat ですね。専用の結合コマンドは要らないと。
ライニー先輩: そのとおり。そして分け方は 3 種類。サイズなら -b、行数なら -l、個数なら -n だね。
リナ: テキストやログは -l を使う。行のとちゅうで切れないからですね。
ライニー先輩: 完璧だね。最後に sha256sum で確かめる。この習慣があれば、元のファイルを安心して消せるよ。

今日の 3 行まとめ

  1. 分けるのは split、戻すのは cat 接頭辞* > 復元ファイル
  2. サイズは -b、行数は -l、個数は -n。テキストやログは -l を使う
  3. 結合したら sha256sum で元ファイルとくらべる。一致してから元ファイルを消す

まとめ / 次に読む

この記事を共有

次の一手