- サーバー
sort・uniqの使い方|重複削除・出現回数カウントをLinuxで一発集計
sort は行を並べ替えるコマンド、uniq は「隣り合った」同じ行をまとめるコマンドです。sort | uniq -c | sort -rn の1行で、重複の削除と出現回数のランキングが作れます。 大事なのは、uniq は隣り合う行しか比べないため、先に sort で同じ行を隣に集めることです。
この記事では、GNU coreutils 9.4 の sort・uniq を Ubuntu 上で実際に動かし、全オプションの実行結果、5万行の架空アクセスログでのランキング作成、重複が残る原因の再現(ロケールで件数が変わる例を含む)、100万行での速度比較を載せています。CSV の特定の列での重複削除や、2つのファイルの差分を取る comm もあわせて紹介します。
検証環境:Ubuntu(glibc 2.39)、GNU coreutils 9.4(sort・uniq・comm)、GNU Awk 5.2.1、2 vCPU・メモリ 7GB。シェルのロケールは未設定(POSIX)で、ロケールを変えた結果はその都度 LC_ALL=... で明記しています。
sort・uniqの早見表(やりたいこと別)
| やりたいこと | コマンド |
|---|---|
| 重複行を削除する | sort file | uniq または sort -u file |
| 出現回数を数える | sort file | uniq -c |
| 出現回数の多い順に並べる | sort file | uniq -c | sort -rn |
| 上位10件だけ見る | sort file | uniq -c | sort -rn | head |
| 重複している行だけ出す(1回ずつ) | sort file | uniq -d |
| 重複している行をすべて出す | sort file | uniq -D |
| 1回しか出ない行だけ出す | sort file | uniq -u |
| 大文字・小文字を区別せずにまとめる | sort -f file | uniq -i |
| 種類がいくつあるか数える | sort -u file | wc -l |
| 数値として並べる/降順 | sort -n / sort -rn |
| 1.5G・200M のような単位つきで並べる | sort -h |
| バージョン番号順に並べる | sort -V |
| CSV の2列目で並べる | sort -t, -k2,2 |
| CSV の2列目で重複削除 | sort -t, -k2,2 -u |
| 元の順番を保ったまま重複削除 | awk '!seen[$0]++' file |
| 2つのファイルの共通行 | comm -12 <(sort a) <(sort b) |
| 片方にだけある行 | comm -23 <(sort a) <(sort b) |
| 結果を同じファイルに上書き | sort -o file file |
| 速く・バイト順で比べる | LC_ALL=C sort ... |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「sort・uniqの使い方|重複削除・出現回数カウントをLinuxで一発集計」
sortとuniqの関係:なぜ「sortしてからuniq」なのか
uniq は「直前の行と同じか」だけを見ます。 ファイル全体から重複を探すわけではありません。そのため、同じ行が離れていると別々に数えられます。
$ printf 'b\na\nb\n' | uniq -c
1 b
1 a
1 b
b が2回あるのに、間に a があるため2つのかたまりとして数えられました。sort で同じ行を隣に集めてから uniq に渡すと、正しく数えられます。
flowchart LR
A[入力<br>b / a / b] --> B[sort<br>a / b / b]
B --> C[uniq -c<br>1 a / 2 b]
C --> D[sort -rn<br>2 b / 1 a]
| 段 | 役割 |
|---|---|
sort |
同じ行を隣り合わせにする |
uniq -c |
隣り合う同じ行を1行にまとめ、件数を先頭につける |
sort -rn |
件数(先頭の数値)の大きい順に並べる |
sortの主要オプション一覧(実行結果つき)
まずは一覧です。下の各節で実行結果を載せています。
| オプション | 意味 | 使いどころ |
|---|---|---|
-n |
数値として比べる | 件数・金額・ID |
-r |
逆順(降順) | ランキング |
-k 開始,終了 |
比べる列(キー)を指定 | 2列目だけで並べる |
-t 文字 |
列の区切り文字 | CSV は -t, |
-u |
同じキーの行を1行にする | 重複削除 |
-h |
K・M・G の単位つき数値 | du -h の結果 |
-V |
バージョン番号順 | 1.2.10 と 1.10.0 |
-f |
大文字・小文字を区別しない | 英単語の並べ替え |
-s |
安定ソート(同じキーは入力順を保つ) | 複数回に分けて並べる |
-o ファイル |
出力先を指定(上書き可) | 元ファイルを更新 |
-M |
月名(Jan〜Dec)順 | 英語の月名 |
-c / -C |
並んでいるかを確認(並べない) | comm の前の確認 |
数値として並べる:-n と -r
オプションなしの sort は文字として比べるため、100 が 2 より前に来ます。 数値なら -n を付けます。
$ cat nums.txt
10
9
100
2
-3
$ sort nums.txt | paste -sd' '
-3 10 100 2 9
$ sort -n nums.txt | paste -sd' '
-3 2 9 10 100
$ sort -rn nums.txt | paste -sd' '
100 10 9 2 -3
(paste -sd' ' は、結果を1行に並べて見やすくするために付けています)
単位つき・バージョン番号・月名:-h -V -M
$ sort -h sizes.txt | paste -sd' '
900K 12M 200M 1.5G 3G
$ sort -rh sizes.txt | paste -sd' '
3G 1.5G 200M 12M 900K
$ sort vers.txt | paste -sd' '
app-1.10.0 app-1.2.0 app-1.2.10 app-1.9.3
$ sort -V vers.txt | paste -sd' '
app-1.2.0 app-1.2.10 app-1.9.3 app-1.10.0
$ sort -M months.txt | paste -sd' '
Jan Feb Mar Dec
-h は du -h の出力の並べ替え、-V はタグやファイル名のバージョン順に便利です。-V なしだと 1.10.0 が 1.2.0 より前になります。
大文字・小文字と重複削除:-f と -u
$ cat fruits.txt
apple
Apple
banana
apple
cherry
banana
banana
$ sort -u fruits.txt | paste -sd' '
Apple apple banana cherry
$ sort -fu fruits.txt | paste -sd' '
apple banana cherry
-u は「キーが同じ行」を1つにします。-f と組み合わせると、Apple と apple も同じとみなされます。 どちらが残るかは入力によるため、表記をそろえたいときは先に tr 'A-Z' 'a-z' で小文字にしておくと結果が安定します。
列を指定する:-t と -k
-k2,2 は「2列目だけ」、-k2 は「2列目から行末まで」をキーにします。 重複削除でこの差が結果に出ます。
$ printf 'x,b,2\ny,b,1\nz,a,9\n' | sort -t, -k2 -u
z,a,9
y,b,1
x,b,2
$ printf 'x,b,2\ny,b,1\nz,a,9\n' | sort -t, -k2,2 -u
z,a,9
x,b,2
-k2 では「b,1」と「b,2」が別のキーになり、2行とも残りました。列で重複削除するときは必ず -k2,2 のように終わりも書くのが安全です。数値として比べる列は -k4,4n のように列ごとに n を付けられます。
安定ソート:-s
$ cat st.csv
5,banana,5
1,Apple,5
2,apple,8
$ sort -t, -k3,3n st.csv
1,Apple,5
5,banana,5
2,apple,8
$ sort -t, -k3,3n -s st.csv
5,banana,5
1,Apple,5
2,apple,8
GNU sort は、キーが同じ行を最後に行全体で比べ直します。 そのため -s なしでは「1,Apple」が前に来ました。-s を付けると、キーが同じ行は入力の順番のまま残ります。「日付で並べたあと、会員IDで並べ直す」のように段階的に並べるときに使います。
出力先を指定する:-o
$ sort -o nums.txt -n nums.txt
$ cat nums.txt | paste -sd' '
-3 2 9 10 100
sort file > file とすると、シェルが先にファイルを空にするため中身が消えます。 同じファイルに書き戻すときは -o を使います。
並んでいるか確認する:-c と -C
$ sort -c unsorted.txt; echo "exit=$?"
sort: unsorted.txt:2: disorder: m01
exit=1
-c は最初に順番が崩れている行を表示し、-C は何も表示せず終了コードだけ返します。シェルスクリプトの条件分岐には -C が向いています。
uniqのオプション一覧(実行結果つき)
| オプション | 意味 |
|---|---|
-c |
各行の前に出現回数をつける |
-d |
重複している行だけを1回ずつ出す |
-D |
重複している行をすべて出す |
-u |
1回しか出ない行だけを出す |
-i |
大文字・小文字を区別しない |
-f N |
先頭から N 個のフィールド(空白区切り)を無視して比べる |
-s N |
先頭から N 文字を無視して比べる |
-w N |
先頭の N 文字だけを比べる |
-c -d -D -u:数える・重複だけ・1回だけ
$ sort fruits.txt | uniq -c
1 Apple
2 apple
3 banana
1 cherry
$ sort fruits.txt | uniq -d
apple
banana
$ sort fruits.txt | uniq -D
apple
apple
banana
banana
banana
$ sort fruits.txt | uniq -u
Apple
cherry
-d は「重複しているものの一覧」、-u は「1回しか出てこないものの一覧」です。たとえば「2回以上ログインした会員」「1回だけ登録された備品」の抽出に使えます。
-i:大文字・小文字をまとめる
$ sort fruits.txt | uniq -i
Apple
banana
cherry
$ sort fruits.txt | uniq -ic
3 Apple
3 banana
1 cherry
表示されるのは、かたまりの最初の行(ここでは Apple)です。 sort の結果で Apple と apple が隣り合っていることが前提なので、ロケールによっては sort -f を先に使うと確実です。
-f -s -w:比べる範囲をずらす・絞る
$ cat ev.log
2026-10-01 login user01
2026-10-01 login user02
2026-10-02 login user01
2026-10-02 logout user01
2026-10-03 logout user03
$ sort -k3 ev.log | uniq -f 2 -c
3 2026-10-01 login user01
1 2026-10-01 login user02
1 2026-10-03 logout user03
-f 2 で日付と操作の2列を飛ばし、ユーザー名だけで数えました。 表示される行は各かたまりの最初の行です。
$ cat codes.txt
A-100 apple
A-200 apple
B-100 banana
B-300 banana
$ uniq -s 6 -c codes.txt
2 A-100 apple
2 B-100 banana
$ uniq -w 1 -c codes.txt
2 A-100 apple
2 B-100 banana
-s 6 は先頭6文字(A-100)を無視して商品名で比べ、-w 1 は先頭1文字(カテゴリ記号)だけで比べています。uniq は区切り文字を指定できない(空白とタブのみ)ため、CSV の列で比べたいときは後述の sort -t, -k か awk を使います。
アクセスログで出現回数ランキングを作る
ここでは架空のアクセスログ(5万行)を Python で生成して集計します。IP アドレスはドキュメント用に予約された 192.0.2.0/24 と 198.51.100.0/24 を使っています。
# gen_log.py:架空のアクセスログを生成する(python3 gen_log.py 50000 > access.log)
import random, sys
random.seed(42)
n = int(sys.argv[1]) if len(sys.argv) > 1 else 50000
ips = [f"192.0.2.{i}" for i in range(1, 51)] + [f"198.51.100.{i}" for i in range(1, 31)]
weights = [1 / (i + 1) for i in range(len(ips))]
urls = ["/", "/items", "/items/42", "/items/7", "/login", "/cart", "/search?q=pen",
"/members/mypage", "/articles/10", "/static/app.js", "/static/style.css", "/favicon.ico"]
uw = [30, 20, 8, 6, 10, 7, 5, 4, 3, 25, 24, 12]
codes = [200] * 90 + [304] * 5 + [404] * 4 + [500]
for i in range(n):
ip = random.choices(ips, weights)[0]
url = random.choices(urls, uw)[0]
t = i * 86400 // n
code = random.choice(codes)
size = random.randint(200, 50000)
print(f'{ip} - - [01/Oct/2026:{t//3600:02d}:{t//60%60:02d}:{t%60:02d} +0900] '
f'"GET {url} HTTP/1.1" {code} {size} "-" "Mozilla/5.0"')
$ python3 gen_log.py 50000 > access.log
$ wc -l access.log
50000 access.log
$ head -2 access.log
192.0.2.13 - - [01/Oct/2026:00:00:00 +0900] "GET / HTTP/1.1" 200 16249 "-" "Mozilla/5.0"
192.0.2.2 - - [01/Oct/2026:00:00:01 +0900] "GET /static/app.js HTTP/1.1" 200 48740 "-" "Mozilla/5.0"
IPアドレス別のアクセス数トップ5
$ cut -d' ' -f1 access.log | sort | uniq -c | sort -rn | head -5
10071 192.0.2.1
4974 192.0.2.2
3330 192.0.2.3
2558 192.0.2.4
1940 192.0.2.5
cut -d' ' -f1 で1列目(IP)を取り出し、いつもの3段で集計しています。awk '{print $1}' でも同じ結果になりました。
URL別・ステータスコード別
$ cut -d' ' -f7 access.log | sort | uniq -c | sort -rn | head -5
9905 /
7970 /static/app.js
7873 /static/style.css
6502 /items
3858 /favicon.ico
$ cut -d' ' -f9 access.log | sort | uniq -c | sort -rn
45127 200
2453 304
1922 404
498 500
条件で絞ってから数える
# 静的ファイルを除いたURLランキング
$ cut -d' ' -f7 access.log | grep -v '^/static/' | sort | uniq -c | sort -rn | head -3
9905 /
6502 /items
3858 /favicon.ico
# 404 を返したURL
$ awk '$9==404 {print $7}' access.log | sort | uniq -c | sort -rn | head -3
386 /
292 /static/app.js
291 /static/style.css
# 何種類のIPからアクセスがあったか
$ cut -d' ' -f1 access.log | sort -u | wc -l
80
「絞り込み(grep・awk)→ 列の取り出し(cut・awk)→ sort | uniq -c | sort -rn」の順に組み立てると、どんな集計も同じ形で書けます。件数が同じ行の並びも固定したいときは sort -k1,1nr -k2,2 のように2つ目のキーを足します。
重複が残る・件数がずれる原因と直し方
| 症状 | 原因 | 直し方 |
|---|---|---|
| 同じ行が2回出てくる | uniq の前に sort していない | sort | uniq にする |
| 見た目は同じなのに別々に数えられる | 行末の空白、CRLF(\r) |
sed 's/\r$//; s/[[:space:]]*$//' で整える |
| 環境によって件数が変わる | ロケール(並べ方の規則)の違い | LC_ALL=C を付ける |
| CSV の列で重複が消えない | -k2 で行末までキーになっている |
-k2,2 にする |
原因1:sortを忘れている
冒頭の例の通り、uniq は隣り合う行しか比べません。 ファイルの一部だけ並んでいる場合も同じことが起きるので、迷ったら必ず sort を挟みます。
原因2:行末の空白・CRLF
Windows で作ったファイルは行末に \r(CR)が付いていることがあります。cat -A で見ると、改行の前の文字が見えます(^M が CR、$ が行末)。
$ cat -A dirty.txt
apple$
apple $
apple^M$
$ sort dirty.txt | uniq -c
1 apple
1 apple
1 apple
3つとも apple に見えますが、別々に数えられました。行末の CR と空白を取り除いてから集計します。
$ sed -e 's/\r$//' -e 's/[[:space:]]*$//' dirty.txt | sort | uniq -c
3 apple
原因3:ロケールの違い(LC_ALL=C との違い)
sort の並べ方は、ロケール(言語・地域の設定)の照合規則に従います。 同じファイルでも、ロケールによって順番が変わります。
$ LC_ALL=C sort fruits.txt | paste -sd' '
Apple apple apple banana banana banana cherry
$ LC_ALL=en_US.UTF-8 sort fruits.txt | paste -sd' '
apple apple Apple banana banana banana cherry
C は文字コード(バイト)の順、en_US.UTF-8 は辞書に近い順です。並び順が違うだけなら集計結果は変わりませんが、照合規則で「同じ重み」とされる文字があると、件数そのものが変わります。 次は、絵文字と一部の漢字を含むファイルでの結果です。
$ cat emo.txt
🍎
🍌
🍎
𠮷
①
$ LC_ALL=C.UTF-8 sort -u emo.txt | paste -sd' '
① 🍌 🍎 𠮷
$ LC_ALL=C.UTF-8 sort emo.txt | uniq -c
1 ①
1 🍌
2 🍎
1 𠮷
$ LC_ALL=ja_JP.UTF-8 sort -u emo.txt | paste -sd' '
① 🍎
$ LC_ALL=ja_JP.UTF-8 sort emo.txt | uniq -c
1 ①
1 🍎
1 🍌
1 🍎
1 𠮷
この環境(glibc 2.39)の ja_JP.UTF-8 では、🍎・🍌・𠮷 が並べ替えの上で同じ扱いになりました。その結果、
sort -uは別の文字を「重複」として消し、4種類が2種類になったsort | uniq -cは🍎が隣に集まらず、2つに分かれて数えられた(uniq はバイトで比べるため)
という2つのずれが起きています。集計や重複削除では LC_ALL=C(UTF-8 の文字を正しく扱いたいなら LC_ALL=C.UTF-8)を付けると、バイト単位で比べるため結果が安定します。 人が読む一覧を辞書順に並べたいときだけ、日本語ロケールを使い分けるとよいでしょう。照合規則の細部は glibc のバージョンで変わることがあるため、結果を残す処理ではロケールを明示しておくのがおすすめです。
100万行で3つの方式を速度比較
同じ「出現回数を数える」でも書き方は3通りあります。100万行のファイルで、それぞれ3回ずつ計測しました。
# bench.sh:使い方 bash bench.sh ファイル名
f=$1
t() { local s=$(date +%s.%N); eval "$1" > /dev/null; local e=$(date +%s.%N); printf '%.2f' "$(echo "$e - $s" | bc)"; }
for L in C ja_JP.UTF-8; do
export LC_ALL=$L
echo "== LC_ALL=$L"
for name in "sort | uniq -c | sort -rn" "sort -u" "awk 連想配列"; do
case $name in
"sort | uniq -c | sort -rn") cmd="sort $f | uniq -c | sort -rn";;
"sort -u") cmd="sort -u $f";;
"awk 連想配列") cmd="awk '{c[\$0]++} END {for (k in c) print c[k], k}' $f | sort -rn";;
esac
r=(); for i in 1 2 3; do r+=($(t "$cmd")); done
echo "$name: ${r[*]} 秒"
done
done
種類が少ない場合(100万行・80種類のIP)
== LC_ALL=C
sort | uniq -c | sort -rn: 0.19 0.21 0.19 秒
sort -u: 0.18 0.18 0.17 秒
awk 連想配列: 0.14 0.14 0.14 秒
== LC_ALL=ja_JP.UTF-8
sort | uniq -c | sort -rn: 1.03 1.03 1.34 秒
sort -u: 1.03 1.13 1.30 秒
awk 連想配列: 0.17 0.17 0.20 秒
種類が多い場合(100万行・約43万種類の会員ID)
== LC_ALL=C
sort | uniq -c | sort -rn: 0.59 0.57 0.50 秒
sort -u: 0.29 0.27 0.28 秒
awk 連想配列: 1.35 1.28 1.40 秒
== LC_ALL=ja_JP.UTF-8
sort | uniq -c | sort -rn: 5.12 3.60 3.37 秒
sort -u: 2.89 7.77 3.31 秒
awk 連想配列: 2.30 2.35 2.75 秒
(共有環境のため、ばらつきがあります。中央値で読んでください)
| 読み取れること | 理由 |
|---|---|
LC_ALL=C にすると sort 系は約3〜10倍速くなった |
照合規則を使わずバイトで比べるため |
| 種類が少ないときは awk が速い | 種類の数だけメモリに持てばよく、全行の並べ替えが不要 |
種類が多いときは LC_ALL=C の sort が速い |
awk は連想配列が大きくなり、結果の sort も必要になる |
件数が要らないなら sort -u が最も軽い |
1回の sort で済む |
使い分けの目安は、「件数が要る → LC_ALL=C sort | uniq -c | sort -rn」「種類が少なく元の順番も保ちたい → awk」「一覧だけ欲しい → LC_ALL=C sort -u」です。awk の書き方の詳細は awk の解説記事に譲り、ここでは比較だけにとどめます。メモリより大きいファイルでも sort は一時ファイルを使って処理できるので、巨大なログでは sort 系が扱いやすい選択肢です。
CSVの特定の列で重複を削除する
注文データから「会員ごとに1行」を取り出す例です。
$ cat orders.csv
order_id,member_id,item,ordered_at
1001,m03,pen,2026-09-01
1002,m01,note,2026-09-01
1003,m03,eraser,2026-09-02
1004,m02,pen,2026-09-03
1005,m01,ruler,2026-09-05
会員IDで重複削除(ヘッダーは残す)
$ { head -n1 orders.csv; tail -n +2 orders.csv | sort -t, -k2,2 -u; }
order_id,member_id,item,ordered_at
1002,m01,note,2026-09-01
1004,m02,pen,2026-09-03
1001,m03,pen,2026-09-01
ヘッダーを head -n1 で先に出し、2行目以降だけを sort しています。ヘッダーまで sort に渡すと、途中に紛れ込みます。
会員ごとに最新の1行を残す
$ { head -n1 orders.csv; tail -n +2 orders.csv | sort -t, -k2,2 -k4,4r | sort -t, -k2,2 -u -s; }
order_id,member_id,item,ordered_at
1005,m01,ruler,2026-09-05
1004,m02,pen,2026-09-03
1003,m03,eraser,2026-09-02
1回目の sort で「会員ID昇順・日付降順」に並べ、2回目の -u -s で各会員の先頭(最新)だけを残します。 2回目の -s がないと、最後の行全体の比較が入り、どの行が残るかが変わることがあります。
元の順番のまま重複削除・件数を数える
$ awk -F, '!seen[$2]++' orders.csv
order_id,member_id,item,ordered_at
1001,m03,pen,2026-09-01
1002,m01,note,2026-09-01
1004,m02,pen,2026-09-03
$ tail -n +2 orders.csv | cut -d, -f2 | sort | uniq -c
2 m01
1 m02
2 m03
sort は並べ替えるので元の順番が変わります。 順番を保ちたいときは awk の !seen[$2]++ が手軽です。なお、値の中にカンマや改行を含む CSV("a,b" のような引用符つき)は、cut や -t, では正しく分割できません。その場合は Python の csv モジュールなど、CSV に対応した道具を使います。
2つのファイルの差分を取る:comm
comm は、並べ替え済みの2つのファイルを比べて「左だけ」「右だけ」「両方」の3列に分けて出すコマンドです。 9月と10月の会員一覧を比べてみます。
$ cat members_sep.txt # 9月
m01
m02
m03
m05
$ cat members_oct.txt # 10月
m02
m03
m04
m05
$ comm members_sep.txt members_oct.txt
m01
m02
m03
m04
m05
1列目(タブなし)が9月だけ、2列目(タブ1つ)が10月だけ、3列目(タブ2つ)が両方です。-1 -2 -3 で消したい列を指定します。
| やりたいこと | コマンド | 結果 |
|---|---|---|
| 両方にある(共通) | comm -12 a b |
m02 m03 m05 |
| 9月だけ(退会など) | comm -23 a b |
m01 |
| 10月だけ(新規) | comm -13 a b |
m04 |
並べ替えていないファイルを渡すと、警告が出て終了コードが1になります。
$ comm unsorted.txt members_oct.txt
m02
m03
comm: file 1 is not in sorted order
m01
m04
m05
comm: input is not in sorted order
bash のプロセス置換 <(sort ファイル) を使うと、一時ファイルなしで並べ替えてから渡せます。
$ comm -12 <(sort unsorted.txt) <(sort members_oct.txt)
m03
sort と comm でロケールが違うと順番の判定がずれるため、LC_ALL=C を付けるなら両方に付けるのがポイントです。行の中身の違いまで見たいときは diff、行単位の集合として比べたいときは comm、と使い分けます。
よくある質問
Q. sort -u と sort | uniq は同じですか?
A. 多くの場合は同じ結果ですが、比べ方が違います。sort -u はキー(-k や -f の指定、ロケールの照合規則)が同じ行を1つにし、uniq はバイトで比べます。この記事の検証でも、ja_JP.UTF-8 では sort -u だけが別の文字を重複として消しました。件数が要るなら sort | uniq -c、一覧だけなら LC_ALL=C sort -u が確実です。
Q. 出現回数が同じ行の順番を固定するには?
A. sort | uniq -c | sort -k1,1nr -k2,2 のように、件数(1列目)の降順のあとに2列目の昇順を足します。毎回同じ並びになるので、結果を比べやすくなります。
Q. uniq -c の先頭の空白を消してCSVにしたいです。
A. uniq -c | awk '{print $2","$1}' で「値,件数」の形にできます。値に空白を含む場合は sed 's/^ *\([0-9]*\) /\1,/' で先頭の件数部分だけを置き換えます。
Q. 大きすぎるファイルでも sort できますか?
A. GNU sort はメモリに入りきらない分を一時ファイルに書き出して処理します。一時ファイルの場所は -T、使うメモリの量は -S(例:-S 50%)、並列数は --parallel で指定できます。詳細は sort --help や GNU coreutils のマニュアルで確認してください。
まとめ
- uniq は隣り合う行しか比べないので、必ず sort してから使う
- 出現回数ランキングは
sort | uniq -c | sort -rn | headの3段で作れる - 数値は
-n、単位つきは-h、バージョンは-V、列は-t, -k2,2(終わりの列まで書く) - 重複が残るときは、sort 忘れ・行末の空白と CRLF・ロケールの3つを確認する
LC_ALL=Cで結果が安定し、100万行の検証では sort が約3〜10倍速くなった- 種類が少なければ awk、多ければ
LC_ALL=Cの sort、一覧だけならsort -u - 2つの一覧の差分は
comm -12/-23/-13とプロセス置換で手早く取れる
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「sort・uniqの使い方|重複削除・出現回数カウントをLinuxで一発集計」
株式会社RJCでは、sort・uniq のような基本コマンドの使いこなしを仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。