【Linux】splitコマンドの使い方|行数・サイズ指定でファイル分割

【Linux】splitコマンドの使い方|行数・サイズ指定でファイル分割

PR Amazonのアソシエイトとして、ITナレッジライフは適格販売により収入を得ています。

記事の文字数:6,333

Linuxのsplitコマンドを使って、大容量のログやCSV・アーカイブファイルを行数(-l)やサイズ(-b・-C)、分割数(-n)で分割する方法を解説します。連番ファイル名や拡張子の指定、catによる再結合、ヘッダー行を維持したCSV分割まで実機例付きで紹介します。

Linuxユーザにお勧めの本 ↗

最新版

ゼロからはじめるLinuxサーバー構築・運用ガイド 第2版 動かしながら学ぶWebサーバーの作り方

難易度
実用性
最新度

Rocky Linux対応。実際にWebサーバーを公開するまでのプロセスを体験できる、最も確実で実践的なガイドブックです。

初心者向け

わかばちゃんと学ぶ サーバー監視

難易度
実用性
読みやすさ

マンガと図解が中心で圧倒的に読みやすい。負荷調査の手法がスッと理解できるようになります。

新しいLinuxの教科書 第2版

難易度
実用性
読みやすさ

一生モノの基礎知識が身につく定番書です。

ゼロからわかる Linuxコマンド200本ノック―基礎知識と頻出コマンドを無理なく記憶に焼きつけよう!

難易度
実用性
習得度

アウトプット重視で記憶に定着しやすい。反復練習でLinux操作が自由自在になります。

エンジニア1年生のための世界一わかりやすいLinuxコマンドの教科書

難易度
実用性
読みやすさ

LinuxLinux [リナックス / ライナックス]オープンソースのOSカーネル環境で数ギガバイトに肥大化したログファイルや大量のCSVCSV [シーエスブイ]Comma-Separated Values。カンマ区切りのデータ形式データ、バックアップ用のアーカイブファイルを扱う際、「エディタやツールで読み込めるように一定の行数ごとに分割したい」「メール添付やストレージ転送の上限サイズに合わせてファイルを分けたい」といった場面があります。

この記事では、ファイルを指定した行数・バイトサイズ・分割数に切り分けられる split コマンドの使い方を解説します。基本オプションの動作から、連番や拡張子を付けた出力ファイル名のカスタマイズ、cat コマンドによる再結合とハッシュ検証、CSVのヘッダー行を各ファイルに付与する応用手順までを具体例とともに紹介します。

この記事を読むことで、テキストデータやバイナリデータの性質に合わせて適切な分割方法を選択し、安全に分割・再結合を行えるようになります。

確認した環境

本記事で解説するコマンドや出力結果は、以下の環境で実機検証を行っています(バージョン確認コマンド: split --version)。

OSOS [オーエス]Operating System。基本ソフトウェアGNU coreutils バージョン
DebianDebian [デビアン]コミュニティ主導で開発される安定性の高いLinuxディストリビューション GNU/Linux 11 (bullseye)GNU coreutils 8.32(split (GNU coreutils) 8.32)
UbuntuUbuntu [ウブントゥ]人気のLinuxディストリビューション 24.04 LTSGNU coreutils 9.4(split (GNU coreutils) 9.4)
AlmaLinux 9.4GNU coreutils 8.32(split (GNU coreutils) 8.32)

Linuxのsplitコマンドとは?基本構文とデフォルトの動作

split コマンドは、1つのファイル(または標準入力)を指定した行数やバイトサイズ、分割数ごとに複数のファイルへ切り分けるコマンドです。GNU coreutils に含まれており、多くのLinuxディストリビューションに標準でインストールされています。

基本構文と引数の役割

split コマンドの基本構文は以下の通りです。

Terminal window
split [オプション] [入力ファイル名 [出力プレフィックス]]
  • [入力ファイル名]: 分割したい元のファイルを指定します。省略した場合や - を指定した場合は、標準入力(stdin)からデータを読み込みます。
  • [出力プレフィックス]: 分割後のファイル名の先頭に付ける文字列(接頭辞)を指定します。省略した場合はデフォルトで x が使われます。

オプションを何も指定せずに実行した場合、デフォルトでは 1,000行ごと にファイルが分割され、カレントディレクトリに xaa、xab、xac… という名前のファイルが順番に生成されます。

Terminal window
# オプションなしで実行した場合(1000行ごとに xaa, xab, ... へ分割される)
split access.log

注意点: split コマンドは元の <入力ファイル名> を削除・変更せず、そのまま残した状態で分割ファイルを新規作成します。ただし、同名の分割ファイル(xaa など)がすでに存在する場合は確認なしで上書きされるため、事前に出力先ディレクトリを確認してください。

主なオプション一覧

split コマンドで頻繁に使用するオプションは以下の通りです。

オプション長い形式役割
-l <行数>--lines=<行数>指定した行数ごとにファイルを分割する(デフォルトは1000行)
-b <サイズ>--bytes=<サイズ>指定したバイトサイズごとにファイルを分割する(単位: K, M, G など)
-C <サイズ>--line-bytes=<サイズ>1ファイルあたり最大 <サイズ> バイトに収まるよう、できるだけ多くの完全な行を格納して分割する(指定サイズを超える長い行がある場合は複数ファイルに分割される)
-n <チャンク指定>--number=<チャンク指定>指定したファイル数(N 個、または行を分断しない l/N など)に分割する
-d--numeric-suffixes[=開始値]ファイル末尾のサフィックスを英字(aa, ab)ではなく数字連番(00, 01)にする(長い形式は開始値も指定可能)
-a <桁数>--suffix-length=<桁数>サフィックスの文字数・桁数を指定する(デフォルトは 2)
なし--additional-suffix=<文字列>分割後のファイル名の末尾に拡張子(.txt や .csv など)を追加する
なし--verbose分割ファイルを生成する直前に、ファイル名を標準エラー出力(画面上)へ表示する

補足(POSIX仕様とGNU拡張について): POSIX規格で標準化されている split のオプションは -l、-b、-a の3つです。-C、-n、-d、--additional-suffix、--filter などはLinux環境(GNU coreutils)で広く利用できる拡張オプションのため、macOSmacOS [マックオーエス]Appleが開発するMac用のオペレーティングシステムやBSD系OSなど異なる実装間でシェルスクリプトを共有する場合は注意してください。

【行数・件数指定】テキストやログを行単位で分割する方法

ログファイルやCSVデータなどのテキストファイルを分割する際は、行の途中で文字が切れないよう、行単位または行数を基準にしたオプションを使用します。事前にファイル全体の行数を把握しておきたい場合は、wcコマンドでファイルの行数をカウントする方法を参考に wc -l で確認しておくと分割数を計算しやすくなります。

指定した行数ごとに分割する(-l)

-l(--lines)オプションに数値を指定すると、その行数ごとにファイルを分割します。以下の例では、7行のテキストファイル sample.txt を作成し、3行ずつに分割しています。

Terminal window
# 検証用に7行のファイルを作成する
$ seq -f "line-%02g" 1 7 > sample.txt
# 3行ごとに分割する
$ split -l 3 sample.txt
# 生成されたファイルとサイズを確認する
$ ls -l x*
-rw-r--r-- 1 yo yo 24 Nov 7 21:55 xaa
-rw-r--r-- 1 yo yo 24 Nov 7 21:55 xab
-rw-r--r-- 1 yo yo 8 Nov 7 21:55 xac
# 各ファイルの中身を確認する
$ head -n 10 x*
==> xaa <==
line-01
line-02
line-03
==> xab <==
line-04
line-05
line-06
==> xac <==
line-07

7行のファイルが3行(xaa)、3行(xab)、端数の1行(xac)の3ファイルに分割されていることが確認できます。なお、ファイルの特定範囲の行だけをピンポイントで抜き出したい場合は、ファイルを分割しなくてもheadとtailコマンドを組み合わせて特定行を抽出する方法で対応できます。

ファイル数(N等分)を指定して分割する(-n と l/N の違い)

「何行ずつ」ではなく「全体をN個のファイルに等分したい」という場合は、-n(--number)オプションを使用します。ただし、単に -n 2 のように数値だけを指定すると、ファイル全体のバイトサイズを単純に2等分するため、テキストの行の途中で分割されてしまう点に注意が必要です。

テキストファイルを行の途中で分断せずにN個のファイルへ振り分けたい場合は、-n l/N(エル・スラッシュ・N)の形式で指定します。

Terminal window
# 1行10バイト×3行(合計30バイト)のファイルを作成する
$ printf "123456789\nabcdefghi\nABCDEFGHI\n" > lines.txt
# 単純な -n 2 では15バイトずつに切られ、2行目の途中で分断される
$ split -n 2 lines.txt chunk_
$ head -n 10 chunk_*
==> chunk_aa <==
123456789
abcde
==> chunk_ab <==
fghi
ABCDEFGHI
# -n l/2 を指定すると、行の区切りを維持したまま2ファイルに分割される
$ split -n l/2 lines.txt lchunk_
$ head -n 10 lchunk_*
==> lchunk_aa <==
123456789
abcdefghi
==> lchunk_ab <==
ABCDEFGHI

また、-n N や -n l/N は入力ファイル全体のサイズを基準に分割するため、シークできないパイプ(|)経由の標準入力では、(※本記事の検証環境である8.32や9.4を含む)GNU coreutils 9.11以前の場合、split: -: cannot determine file size というエラーになります。GNU coreutils 9.12以降では、シークできない入力を一時ファイルへコピーしてからサイズを取得するため、パイプ経由でも -n N や -n l/N を使用できます(一時ファイルを使用するため、入力データと同程度の空き容量が必要になる点には注意してください)。

なお、バージョンに依存せずパイプからの標準入力を行単位でN個のファイルへ振り分けたい場合は、1行ずつ順番(ラウンドロビン方式)に割り振る -n r/N を使用できます。

Terminal window
# 標準入力から受け取った行を2つのファイルへ交互(ラウンドロビン)に振り分ける
$ printf "line1\nline2\nline3\nline4\n" | split -n r/2 - rr_
$ head -n 10 rr_*
==> rr_aa <==
line1
line3
==> rr_ab <==
line2
line4

【サイズ指定】大容量ファイルをバイト単位で分割する方法

アーカイブファイル(.tar.gz や .zip)やディスクイメージ、巨大ログファイルを一定のファイルサイズ以下に収めたい場合は、-b または -C オプションを使用します。

指定したバイトサイズごとに分割する(-b)

-b(--bytes)オプションは、改行コードの有無に関係なく、指定したバイトサイズごとにデータを厳密に切り分けます。tarコマンドで作成した圧縮アーカイブやバイナリファイルを分割する際に適しています。

サイズ指定には以下の単位サフィックスを使用できます。

単位指定計算基準意味(例)
K, M, G, T(または KiB, MiB, GiB)1024の累乗(2進接頭辞)10M = 10 × 1024 × 1024 バイト(10,485,760バイト)
KB, MB, GB, TB1000の累乗(10進接頭辞)10MB = 10 × 1000 × 1000 バイト(10,000,000バイト)
単位なしバイト数1024 = 1024バイト
Terminal window
# backup.tar.gz を 100MiB ごとに backup_part_aa, backup_part_ab, ... へ分割する
split -b 100M backup.tar.gz backup_part_

行の途中を分断せずに最大サイズ以下で分割する(-C)

テキストファイルをサイズ上限で分割したいものの、-b のように行の途中で文字が切れるのを防ぎたい場合は、-C(--line-bytes)オプションを使用します。-C(--line-bytes)オプションは、指定したサイズを超えない範囲で、できるだけ多くの完全な行を1ファイルに格納するように分割します。

ただし、指定サイズよりも長い行が存在する場合は、その行も複数のファイルに分割されます。そのため、すべての行を必ず維持できるわけではない点に注意してください。

先ほどと同じ1行10バイト(9文字+改行1バイト)×3行の lines.txt に対して、上限15バイトで -b 15 と -C 15 を比較すると違いが明確になります。

Terminal window
# -b 15 の場合:改行を無視して15バイト目で強制的に分割される
$ split -b 15 lines.txt byte_
$ head -n 10 byte_*
==> byte_aa <==
123456789
abcde
==> byte_ab <==
fghi
ABCDEFGHI
# -C 15 の場合:15バイト以内に収まる完全な行(1行=10バイト)単位で分割される
$ split -C 15 lines.txt linebyte_
$ head -n 10 linebyte_*
==> linebyte_aa <==
123456789
==> linebyte_ab <==
abcdefghi
==> linebyte_ac <==
ABCDEFGHI

ログ解析ツールやスクリプトへ入力するテキストファイルをサイズ基準で分割する場合は、通常の長さの行を維持できる -C オプションが便利です。ただし、指定サイズを超える長い行は分割されるため、事前に行の最大サイズを確認しておきましょう。

分割後のファイル名(プレフィックス・連番・拡張子)をカスタマイズする

デフォルトの出力ファイル名(xaa, xab)は、何のファイルか判別しにくく拡張子も付きません。実務ではプレフィックス、数字連番(-d)、桁数(-a)、追加サフィックス(--additional-suffix)を組み合わせて分かりやすいファイル名に整えます。

プレフィックス・数字連番(-d)・拡張子(—additional-suffix)を組み合わせる

以下の例では、プレフィックスに part_、サフィックスに数字連番(-d)、末尾の拡張子に .txt(--additional-suffix=.txt)を指定し、さらに --verbose で生成されるファイル名を標準エラー出力(画面上)に出力しています。

Terminal window
$ split -l 3 -d --additional-suffix=.txt --verbose sample.txt part_
creating file 'part_00.txt'
creating file 'part_01.txt'
creating file 'part_02.txt'

このように指定すると、part_00.txt、part_01.txt、part_02.txt のように連番と拡張子が付いた扱いやすいファイル名で出力されます。また、--numeric-suffixes=1 のように開始値を指定すれば、part_01.txt から連番を始めることも可能です。

分割数が多くなる場合の桁数指定(-a)と注意点

サフィックスの桁数はデフォルトで2文字(-a 2)です。-a オプションを明示せずに -d で90個を超えるファイルを出力した場合、GNU split は辞書順(文字コード順)の並びを維持するために、89 の次から自動的に桁数を増やして 9000、9001… というファイル名に切り替えます。

Terminal window
# -a を省略して95ファイルに分割した場合、89の次から9000へ桁数が自動拡張される
$ seq 1 95 | split -l 1 -d - p_
$ ls p_* | tail -n 7
p_88
p_89
p_9000
p_9001
p_9002
p_9003
p_9004

一方で、-d -a 2 のように桁数を明示的に固定した状態で100個を超えるファイルを生成しようとすると、00〜99を使い切った時点で split: output file suffixes exhausted というエラーになり処理が中断します。

Terminal window
# -d -a 2 で101行を1行ずつ分割しようとするとサフィックス上限に達してエラーになる
$ seq 1 101 | split -l 1 -d -a 2 - p_
split: output file suffixes exhausted

100個以上のファイルに分割する可能性がある場合は、あらかじめ -a 3(000〜999)や -a 4(0000〜9999)を指定して桁数を揃えておくと、桁数の途中変化や上限エラーを防げます。

分割したファイルを再結合する方法と応用テクニック

分割したファイルを元の1つのファイルに戻す方法と、実務で役立つCSVヘッダー維持のテクニックを紹介します。

catコマンドで再結合しハッシュ値で整合性を確認する

split で分割したファイルは、cat コマンドと出力リダイレクト(>)を使って順番に連結するだけで元のファイルへ復元できます。シェルのワイルドカード(*)は辞書順(アルファベット順・数字の文字列順)に展開されるため、split の連番サフィックス通りに結合されます。

再結合した後は、特にバイナリファイルや圧縮アーカイブの場合にデータが破損していないか sha256sum(または md5sum)でハッシュ値を比較して検証すると確実です。

Terminal window
# 分割された chunk_aa, chunk_ab を結合して restored.txt に復元する
$ cat chunk_* > restored.txt
# 元のファイルと復元したファイルのSHA-256ハッシュ値が一致するか確認する
$ sha256sum lines.txt restored.txt
3cc47a1f1d96e84d859184e76ce595bea77ad46179a01061aba18d908996f262 lines.txt
3cc47a1f1d96e84d859184e76ce595bea77ad46179a01061aba18d908996f262 restored.txt

注意: cat part_* > part_all.txt のように、結合先のファイル名がワイルドカード part_* にマッチしてしまう名前だと、コマンドを再実行した際に出力ファイル自身が入力に含まれてしまいます。GNU cat は cat: part_all.txt: input file is output file というエラーを出して該当ファイルをスキップしますが、他の実装や処理方法によっては意図しないデータの混入や破損の原因になります。結合後のファイル名はワイルドカードに一致しない別名(restored.txt など)にするか、別ディレクトリへ出力してください。

【応用】CSVファイルのヘッダー行(1行目)をすべての分割ファイルに付与する

CSVファイルの1行目にあるヘッダー(カラム名)をすべての分割ファイルに引き継ぎたい場合は、tail -n +2 と GNU split の --filter オプションを組み合わせて分割します。

1行目にカラム名があるCSVファイルをそのまま split で分割すると、2つ目以降のファイルにはヘッダー行が含まれなくなります。GNU split の --filter=COMMAND オプションを使うと、各分割データが出力される際に任意のシェルコマンド(出力ファイル名は環境変数 $FILE で参照可能)を通すことができます。これを利用して、tail -n +2 で2行目以降のデータ行だけを split に渡しつつ、--filter 内で1行目のヘッダーを先頭に出力してからデータ行を書き込むことで、すべての分割ファイルにヘッダー行を付与できます。

Terminal window
# ヘッダー付きのCSVファイルを作成する
$ printf "id,name,role\n1,alice,admin\n2,bob,user\n3,charlie,user\n4,dave,guest\n" > users.csv
# 2行目以降を2行ずつ分割し、各ファイルの先頭に1行目のヘッダーを付与する
$ tail -n +2 users.csv | split -l 2 -d --additional-suffix=.csv --filter='{ head -n 1 users.csv; cat; } > "$FILE"' - users_part_
# 分割された各CSVファイルにヘッダー行が入っていることを確認する
$ head -n 10 users_part_*.csv
==> users_part_00.csv <==
id,name,role
1,alice,admin
2,bob,user
==> users_part_01.csv <==
id,name,role
3,charlie,user
4,dave,guest

この方法を使えば、大量のCSVデータをバッチ処理やインポートツール向けに分割する際も、各ファイルをそのまま有効なヘッダー付きCSVとして扱えます。

なお、この方法は1レコードが1行に収まる一般的なCSVを対象としています。CSVではダブルクォーテーションで囲まれたフィールド内に改行を含めることができますが、split -l はCSVのレコード構造を認識せず、改行単位で分割します。そのため、フィールド内に改行を含むCSVを扱う場合は、CSV形式を解析できる専用ツールやプログラムを使用してください。

まとめ:splitコマンドで大容量ファイルを安全に分割・管理しよう

本記事では、Linuxの split コマンドによるファイルの分割・再結合の方法について解説しました。

記事の要点を以下にまとめます。

  • オプションなしで split を実行すると、デフォルトで 1,000行ごと に xaa、xab… というファイルへ分割される。
  • テキストファイルを行単位で分割する際は、行数指定の -l <行数>、指定サイズ内で完全な行を格納する -C <サイズ>(指定サイズを超える長い行は分割される点に注意)、または分割数指定の -n l/<分割数> を使用する。
  • バイナリファイルや圧縮アーカイブを一定の容量ごとに分割する際は、バイトサイズ指定の -b <サイズ>(例: -b 100M)を使用する。
  • -d(数字連番)、-a <桁数>(桁数指定)、--additional-suffix=<拡張子> とプレフィックスを組み合わせることで、part_000.csv のような管理しやすいファイル名で出力できる。
  • 分割したファイルは cat <プレフィックス>* > <復元ファイル名> で再結合でき、sha256sum で元ファイルとの一致を検証できる。

ログ解析やデータの前処理で使うその他のテキスト処理コマンドについては、Linuxのテキスト処理・検索コマンドの使い方まとめもあわせて参考にしてください。


以上で本記事の解説を終わります。
よいITライフを!
ITナレッジライフ 運営者
この記事を書いた人

Z (ITナレッジライフ)

現役のITエンジニア。Linux、プログラミング、IT用語など、日々の業務で得た「痒いところに手が届く」技術情報を発信しています。

プロフィールと編集ポリシーを見る →

Linuxユーザにお勧めの本 ↗

最新版

ゼロからはじめるLinuxサーバー構築・運用ガイド 第2版 動かしながら学ぶWebサーバーの作り方

難易度
実用性
最新度

Rocky Linux対応。実際にWebサーバーを公開するまでのプロセスを体験できる、最も確実で実践的なガイドブックです。

人気記事


記事を評価

Thanks!
目次
Scroll to Top