今回はLinuxコマンドであるsortコマンドについて解説します
sortコマンドは、ファイルや他のコマンドの出力を行単位で並べ替えるコマンドです
ログの集計やCSVの並べ替え、重複行の削除など、インフラの現場でも毎日のように使うコマンドなので、ぜひ覚えて帰ってくださいね!
※注 本文の△は半角スペースに置き換えてください。わかりやすくするために△で記述してます
sortコマンドとは??
sortコマンドは、テキストを行単位で並べ替えて表示するコマンドです
名前はそのまま英語の「sort(並べ替える、分類する)」から来ています
並べ替えた結果は画面(標準出力)に表示されるだけで、元のファイルは変更されません
文字列の順番だけでなく、数値順・逆順・バージョン番号順や、「3列目の数値で並べ替える」といった列(フィールド)を指定した並べ替えもできます
grepやawk、uniqなどのコマンドとパイプでつないで使うことが多く、ログの集計では欠かせない存在です
この記事の実行結果は、GNU coreutils 9.4のsort(Ubuntu 24.04)を一般ユーザー(user)で実行して確認しています
sortコマンドの主なオプション
sortコマンドの主なオプションは次のとおりです
| オプション | 意味 |
|---|---|
| -r (–reverse) | 並べ替えの結果を逆順(降順)にするオプション |
| -n (–numeric-sort) | 行の先頭にある数字を「数値」として比べ、小さい順に並べるオプション |
| -h (–human-numeric-sort) | 単位まで考えて正しく並べるオプション |
| -k (–key) | 並べ替えに使う列(キー)を指定するオプション |
| -t (–field-separator) | 列の区切り文字を指定するオプション(省略したときは空白が区切りになります) |
| -u (–unique) | 並べ替えたうえで、同じ内容の行を1行にまとめるオプション |
| -f (–ignore-case) | 大文字と小文字を区別せずに並べるオプション |
| -V (–version-sort) | 文字列の中の数字を数値として扱い、バージョン番号やファイル名を自然な順番に並べるオプション |
| -c (–check) | 並べ替えはせずに、ファイルがすでに並んでいるかどうかだけをチェックするオプション |
| -o (–output) | 並べ替えた結果を、画面ではなく指定したファイルに書き込むオプション |
| -s (–stable) | キーが同じ行どうしを、元の順番のまま並べるオプション |
ここからは、テスト用のディレクトリsort-testの中に練習用ファイルを作って説明します
次のコマンドで同じファイルを作れるので、一緒に試してみてください
mkdir△sort-test
cd△sort-test
printf△”banana\napple\ncherry\nBanana\napple\ndate\n”△>△fruits.txt
printf△”10\n2\n100\n1\n25\n”△>△nums.txt
printf△”2M\n512K\n1G\n100K\n3K\n”△>△sizes.txt
printf△”app-1.10.0\napp-1.2.0\napp-1.9.3\napp-1.2.10\n”△>△versions.txt
printf△”high△review\nlow△cleanup\nhigh△deploy\nlow△backup\n”△>△tasks.txt
printf△”id,name,dept,score\n1,suzuki,dev,88\n2,tanaka,sales,72\n3,sato,dev,95\n4,ito,sales,88\n5,kato,infra,72\n”△>△users.csv
printf△”192.168.0.10△GET△/index.html△200\n192.168.0.25△GET△/about.html△200\n192.168.0.10△GET△/login△401\n192.168.0.31△GET△/index.html△200\n192.168.0.10△POST△/login△200\n192.168.0.25△GET△/index.html△404\n192.168.0.10△GET△/mypage△200\n192.168.0.31△GET△/about.html△200\n”△>△access.log
touch△-d△”2026-11-01△10:00″△*.txt△users.csv△access.log
# 作成したディレクトリの構成を確認する
ls△-l
実行結果:
total 28
-rw-rw-r– 1 user user 251 Nov 1 10:00 access.log
-rw-rw-r– 1 user user 38 Nov 1 10:00 fruits.txt
-rw-rw-r– 1 user user 14 Nov 1 10:00 nums.txt
-rw-rw-r– 1 user user 19 Nov 1 10:00 sizes.txt
-rw-rw-r– 1 user user 47 Nov 1 10:00 tasks.txt
-rw-rw-r– 1 user user 98 Nov 1 10:00 users.csv
-rw-rw-r– 1 user user 42 Nov 1 10:00 versions.txt
# ファイルの中身を確認する
cat△fruits.txt
実行結果:
banana
apple
cherry
Banana
apple
date
cat△nums.txt
実行結果:
10
2
100
1
25
cat△sizes.txt
実行結果:
2M
512K
1G
100K
3K
cat△versions.txt
実行結果:
app-1.10.0
app-1.2.0
app-1.9.3
app-1.2.10
cat△tasks.txt
実行結果:
high review
low cleanup
high deploy
low backup
cat△users.csv
実行結果:
id,name,dept,score
1,suzuki,dev,88
2,tanaka,sales,72
3,sato,dev,95
4,ito,sales,88
5,kato,infra,72
cat△access.log
実行結果:
192.168.0.10 GET /index.html 200
192.168.0.25 GET /about.html 200
192.168.0.10 GET /login 401
192.168.0.31 GET /index.html 200
192.168.0.10 POST /login 200
192.168.0.25 GET /index.html 404
192.168.0.10 GET /mypage 200
192.168.0.31 GET /about.html 200
以降のコマンドは、すべてsort-testの中で実行します
この記事の環境のロケールはC.UTF-8です
大文字と小文字の並び順などはロケールによって変わるので、詳しくは後半の「ロケールによって並び順が変わる」で解説します
-r (–reverse)
並べ替えの結果を逆順(降順)にするオプションです
文字列ならzからaの順に、-nと組み合わせれば大きい数値から順に並びます
# 文字列を逆順に並べる
sort△-r△fruits.txt
実行結果:
date
cherry
banana
apple
apple
Banana
# 数値の大きい順に並べる(-nと組み合わせる)
sort△-nr△nums.txt
実行結果:
100
25
10
2
1
-n (–numeric-sort)
行の先頭にある数字を「数値」として比べ、小さい順に並べるオプションです
-nを付けないと文字列として1文字ずつ比べるので、「100」や「10」が「2」より前に来てしまいます
# -nなし(文字列として比べる)
sort△nums.txt
実行結果:
1
10
100
2
25
# 1文字目から順に文字として比べるので、1→10→100→2→25の順になってしまいます
# -nあり(数値として比べる)
sort△-n△nums.txt
実行結果:
1
2
10
25
100
# 数値の小さい順に正しく並びます
-h (–human-numeric-sort)
「3K」「2M」「1G」のような単位付きの数値(du -hなどの出力)を、単位まで考えて正しく並べるオプションです
POSIXの規格にはない拡張オプションで、GNU版のsortで使えます(ほかの実装では使えない場合があります)
# -hで単位付きの数値を並べる
sort△-h△sizes.txt
実行結果:
3K
100K
512K
2M
1G
# K→M→Gの順に、本当の大きさの順で並びます
# -nだと単位が無視される
sort△-n△sizes.txt
実行結果:
1G
2M
3K
100K
512K
# 1、2、3、100、512という数字だけで比べるので、1Gが先頭に来てしまいます
-k (–key)
並べ替えに使う列(キー)を指定するオプションです
「-k2,2」のように開始列と終了列をカンマでつないで書くと、その範囲だけを比べます(列は空白で区切って数えます)
# 2列目(作業名)で並べる
sort△-k2,2△tasks.txt
実行結果:
low backup
low cleanup
high deploy
high review
# 2列目のbackup→cleanup→deploy→reviewの順に並びます
-t (–field-separator)
列の区切り文字を指定するオプションです(省略したときは空白が区切りになります)
CSVファイルなら「-t,」のようにカンマを指定し、-kと組み合わせて使います
# カンマ区切りの4列目(score)を数値として並べる
sort△-t,△-k4,4n△users.csv
実行結果:
id,name,dept,score
2,tanaka,sales,72
5,kato,infra,72
1,suzuki,dev,88
4,ito,sales,88
3,sato,dev,95
# 点数の低い順に並びます
# 見出し行のscoreは数値ではないので0として扱われ、先頭に来ます
-u (–unique)
並べ替えたうえで、同じ内容の行を1行にまとめるオプションです
「sort | uniq」と同じ結果になります(-kを指定したときは、キーが同じ行を重複とみなします)
sort△-u△fruits.txt
実行結果:
Banana
apple
banana
cherry
date
# 2行あったappleが1行にまとまりました
# 大文字のBananaと小文字のbananaは別の文字列として扱われます
-f (–ignore-case)
大文字と小文字を区別せずに並べるオプションです
-uと組み合わせると、大文字と小文字だけが違う行も重複として1行にまとまります
# 大文字と小文字を区別せずに並べる
sort△-f△fruits.txt
実行結果:
apple
apple
Banana
banana
cherry
date
# Bananaとbananaが区別されずに、appleの後ろに並んで表示されます
# -uと組み合わせる
sort△-fu△fruits.txt
実行結果:
apple
banana
cherry
date
# Bananaとbananaは同じとみなされ、ファイルの中で先に出てくるbananaだけが残ります
-V (–version-sort)
文字列の中の数字を数値として扱い、バージョン番号やファイル名を自然な順番に並べるオプションです
POSIXの規格にはない拡張オプションで、GNU版のsortで使えます(ほかの実装では使えない場合があります)
# -Vなし
sort△versions.txt
実行結果:
app-1.10.0
app-1.2.0
app-1.2.10
app-1.9.3
# 文字列として比べるので、1.10.0が1.2.0より前に来てしまいます
# -Vあり
sort△-V△versions.txt
実行結果:
app-1.2.0
app-1.2.10
app-1.9.3
app-1.10.0
# 1.2.0→1.2.10→1.9.3→1.10.0と、バージョン番号の順に並びます
-c (–check)
並べ替えはせずに、ファイルがすでに並んでいるかどうかだけをチェックするオプションです
並んでいなければ最初に順番が崩れている行を表示し、終了ステータス1を返します
# 並んでいないファイルをチェックする
sort△-c△nums.txt
実行結果:
sort: nums.txt:3: disorder: 100
echo△$?
実行結果:
1
# -nを付けていないので文字列として比べられ、3行目の「100」で順番が崩れていると判定されました
# 並んでいないので、終了ステータスは1になります
# 並べ替えた結果をチェックする
sort△-n△nums.txt△|△sort△-nc
echo△$?
実行結果:
0
# 並んでいれば何も表示されず、終了ステータスは0になります
-o (–output)
並べ替えた結果を、画面ではなく指定したファイルに書き込むオプションです
入力と同じファイルを指定しても正しく上書きできるのが、リダイレクト(>)との大きな違いです
sort△-o△sorted.txt△fruits.txt
cat△sorted.txt
実行結果:
Banana
apple
apple
banana
cherry
date
# 並べ替えた結果がsorted.txtに保存されました
# sorted.txtがすでにあるときは、確認なしで上書きされるので注意してください
-s (–stable)
キーが同じ行どうしを、元の順番のまま並べるオプションです(安定ソートといいます)
-sがないと、キーが同じ行は最後に行全体を比べて並べ直されます
POSIXの規格にはない拡張オプションで、GNU版のsortで使えます(ほかの実装では使えない場合があります)
# -sなし(1列目で並べる)
sort△-k1,1△tasks.txt
実行結果:
high deploy
high review
low backup
low cleanup
# highどうし、lowどうしは行全体で比べ直されるので、作業名のアルファベット順になります
# -sあり
sort△-s△-k1,1△tasks.txt
実行結果:
high review
high deploy
low cleanup
low backup
# highどうし、lowどうしは元のファイルの順番(review→deploy、cleanup→backup)のまま並びます
基本的な使い方
sortコマンドの基本的な構文は「sort△オプション△ファイル名」です
ファイル名を省略すると標準入力を読むので、パイプで他のコマンドの出力を受け取って並べ替えることもできます
オプションを付けないと、行の先頭から1文字ずつ比べて昇順に並べます
# ファイルの中身を並べ替える
sort△fruits.txt
実行結果:
Banana
apple
apple
banana
cherry
date
# この環境(C.UTF-8)では大文字が小文字より前に並ぶので、Bananaが先頭に来ます
# 元のfruits.txtの中身は変わりません
# パイプで受け取った出力を並べ替える
printf△”cherry\napple\nbanana\n”△|△sort
実行結果:
apple
banana
cherry
複数のキーで並べ替える
-kは何個でも指定でき、先に書いたキーから順番に比べます
1つ目のキーが同じ行は、2つ目のキーで比べるという仕組みです
また、「-k4,4nr」のようにキーの後ろにnやrを付けると、そのキーだけに数値順や逆順を指定できます
# 部署(3列目)の順に並べ、同じ部署の中では点数(4列目)の高い順にする
sort△-t,△-k3,3△-k4,4nr△users.csv
実行結果:
id,name,dept,score
3,sato,dev,95
1,suzuki,dev,88
5,kato,infra,72
4,ito,sales,88
2,tanaka,sales,72
# dev→infra→salesの順に並び、同じ部署の中は点数の高い順になります
# 見出し行のdeptはdevより前の文字列なので、先頭に来ます
# 点数の高い順に並べ、同じ点数なら名前(2列目)の順にする
sort△-t,△-k4,4nr△-k2,2△users.csv
実行結果:
3,sato,dev,95
4,ito,sales,88
1,suzuki,dev,88
5,kato,infra,72
2,tanaka,sales,72
id,name,dept,score
# 88点のitoとsuzuki、72点のkatoとtanakaが、それぞれ名前順に並びます
# 見出し行は0点として扱われるので、今度は一番最後に来ます
-k2と-k2,2の違い
「-k2」のように終了列を書かないと、「2列目から行末まで」がキーになります
2列目だけで比べたいときは、「-k2,2」のように終了列まで書きましょう
# 事前準備:名前・点数・ランクのファイルを作る
printf△”sato△10△B\ntanaka△10△A\nsuzuki△20△C\n”△>△members.txt
cat△members.txt
実行結果:
sato 10 B
tanaka 10 A
suzuki 20 C
# -k2:2列目から行末まで(10 Bと10 A)を比べる
sort△-k2△members.txt
実行結果:
tanaka 10 A
sato 10 B
suzuki 20 C
# 点数が同じ10の行は、3列目のランク(A→B)の順になります
# -k2,2:2列目だけを比べる
sort△-k2,2△members.txt
実行結果:
sato 10 B
tanaka 10 A
suzuki 20 C
# 点数が同じ10の行は、行全体で比べ直されて名前(sato→tanaka)の順になります
sortとuniqで出現回数を集計する
sortが一番活躍するのが、uniqコマンドと組み合わせた集計です
uniqは「隣り合った」同じ行しかまとめられないので、先にsortで同じ行を隣どうしに集めておく必要があります
uniq -cを付けると、まとめた行の数(出現回数)を行の先頭に表示してくれます
# sortせずにuniq -cすると、離れた同じ行はまとまらない
awk△'{print△$1}’△access.log△|△uniq△-c
実行結果:
1 192.168.0.10
1 192.168.0.25
1 192.168.0.10
1 192.168.0.31
1 192.168.0.10
1 192.168.0.25
1 192.168.0.10
1 192.168.0.31
# 同じIPアドレスが離れた行にあるので、すべて1回として数えられてしまいます
# sortしてからuniq -cすると、IPアドレスごとの件数になる
awk△'{print△$1}’△access.log△|△sort△|△uniq△-c
実行結果:
4 192.168.0.10
2 192.168.0.25
2 192.168.0.31
# さらにsort -nrで件数の多い順に並べる(アクセス数ランキング)
awk△'{print△$1}’△access.log△|△sort△|△uniq△-c△|△sort△-nr
実行結果:
4 192.168.0.10
2 192.168.0.31
2 192.168.0.25
# 同じ件数の行は、-rの影響で行全体の逆順(.31→.25)に並びます
# よくアクセスされているページの上位3件を表示する
awk△'{print△$3}’△access.log△|△sort△|△uniq△-c△|△sort△-nr△|△head△-n△3
実行結果:
3 /index.html
2 /login
2 /about.html
# 2回以上出てくる行だけを表示する(uniq -d)
sort△fruits.txt△|△uniq△-d
実行結果:
apple
「sort | uniq -c | sort -nr」はログ解析の定番パターンなので、ぜひセットで覚えておいてください
awkの使い方は、記事の最後にある関連記事で詳しく解説しています
sortコマンドの実践的な活用例
実際の現場でよく使われるsortコマンドの活用例をご紹介します
# 見出し行を残したまま、CSVを点数の高い順に並べる
(head△-n△1△users.csv△&&△tail△-n△+2△users.csv△|△sort△-t,△-k4,4nr)
実行結果:
id,name,dept,score
3,sato,dev,95
1,suzuki,dev,88
4,ito,sales,88
2,tanaka,sales,72
5,kato,infra,72
# 1行目だけをheadで先に表示し、2行目以降をsortで並べ替えています
# IPアドレスを正しい順番に並べる
printf△”10.0.0.100\n10.0.0.25\n10.0.0.3\n”△|△sort
実行結果:
10.0.0.100
10.0.0.25
10.0.0.3
printf△”10.0.0.100\n10.0.0.25\n10.0.0.3\n”△|△sort△-V
実行結果:
10.0.0.3
10.0.0.25
10.0.0.100
# 普通のsortでは100→25→3の順になりますが、-Vを付けると3→25→100の順に並びます
# ファイルを行数の多い順に並べる
wc△-l△*.txt△|△sort△-nr
実行結果:
33 total
6 sorted.txt
6 fruits.txt
5 sizes.txt
5 nums.txt
4 versions.txt
4 tasks.txt
3 members.txt
# 一番上のtotalは、すべてのファイルの合計行数です
# sorted.txtとmembers.txtは、前の節で作ったファイルです
# 容量の大きいディレクトリを上位5件表示する
sudo△du△-sh△/var/log/*△|△sort△-hr△|△head△-n△5
# 結果は環境によって違うので省略しています
# du -hの出力は単位付きなので、-nではなく-hを使うのがポイントです
トラブルシューティング
sortコマンドを使うときによくあるつまずきと、その解決方法です
同じファイルにリダイレクトすると中身が消える
「sort△fruits.txt△>△fruits.txt」のように、並べ替えた結果を同じファイルにリダイレクトするのは絶対にNGです
※シェルは>を見た時点でファイルを空にするので、sortが読む前に中身が消えてしまいます
同じファイルに書き戻したいときは、-oオプションを使いましょう
# 事前準備:fruits.txtをコピーして練習用のwork.txtを作る
cp△fruits.txt△work.txt
# NG:リダイレクトで同じファイルに書き込む
sort△work.txt△>△work.txt
wc△-c△work.txt
実行結果:
0 work.txt
# 中身が消えて0バイトになってしまいました
# OK:-oで同じファイルに書き戻す
cp△fruits.txt△work.txt
sort△-o△work.txt△work.txt
cat△work.txt
実行結果:
Banana
apple
apple
banana
cherry
date
# 並べ替えた結果で正しく上書きされました
# 練習用のファイルを削除する
rm△work.txt
大事なファイルで試すと元に戻せないので、注意してください
ロケールによって並び順が変わる
sortの並び順は、環境変数LANGやLC_ALLで決まるロケールの影響を受けます
同じファイルでも、環境によって大文字と小文字の順番などが変わることがあります
# Cロケール(文字コード順)
LC_ALL=C△sort△fruits.txt
実行結果:
Banana
apple
apple
banana
cherry
date
# 大文字のBananaが、小文字の行より前に来ます
# 日本語ロケール
LC_ALL=ja_JP.UTF-8△sort△fruits.txt
実行結果:
Banana
apple
apple
banana
cherry
date
# この環境では、アルファベットの並びはCロケールと同じになりました
# 英語ロケール
LC_ALL=en_US.UTF-8△sort△fruits.txt
実行結果:
apple
apple
banana
Banana
cherry
date
# 大文字と小文字をほぼ区別しない辞書順になり、bananaとBananaが並びます
# 使えるロケールを確認する
locale△-a
# 結果は環境によって違うので省略しています
シェルスクリプトなどで、どの環境でも同じ並び順にしたいときは、LC_ALL=Cを付けて実行するのがおすすめです
Cロケールは文字コード順で比べるだけなので、処理が速いというメリットもあります
まとめ
いかがでしたでしょうか
今回はsortコマンドについてまとめてみました
sortは-nや-hで数値順、-rで逆順、-tと-kで列を指定して並べ替えられるコマンドです
uniq -cと組み合わせた「sort | uniq -c | sort -nr」は、ログ集計の定番パターンです
同じファイルに書き戻すときは、リダイレクトではなく-oを使うこともあわせて覚えておきましょう
ログ解析やCSVの整理でとても役に立つので、ぜひマスターしてください!
