閉じる

Bashのuniqコマンドで重複行を削除・抽出する方法:sortとの併用や主要オプションの解説

LinuxやmacOSのターミナルでテキストデータを処理する際、データの重複を効率的に整理したい場面は頻繁にあります。

Bash環境で標準的に利用されるuniqコマンドは、入力されたテキストから重複した内容を一本化したり、逆に重複している行だけを抽出したりするのに非常に便利です。

本記事では、uniqコマンドの基本的な使い方から、実務で不可欠なsortコマンドとの連携、便利な主要オプションの活用方法までを詳しく解説します。

uniqコマンドの基本概念と注意点

uniqコマンドは、入力されたテキストデータの中で「連続して重複している行」を一つにまとめるためのツールです。

ここで重要なのは、「連続していない重複行は削除されない」という点です。

例えば、同じ内容の行が1行目と3行目にあり、2行目に異なる内容がある場合、uniqコマンドを単体で実行してもそれらは重複と見なされません。

この特性を理解していないと、意図した通りの結果が得られないため注意が必要です。

そのため、ファイル全体の重複を完全に排除したい場合には、後述するように事前にデータを並べ替える処理がセットで行われます。

sortコマンドとの併用が必須となる理由

前述の通り、uniqは隣接する行のみを比較するため、ファイル全体の重複行を削除するには事前にsortコマンドを実行して重複行を隣り合わせにする必要があります。

Bashのパイプ(|)機能を利用して、sortの結果をuniqに渡すのが最も一般的な使い方です。

具体的な動作を確認するために、以下のサンプルファイル(data.txt)を例に考えてみましょう。

Shell
# サンプルファイルの内容確認
cat data.txt
実行結果
apple
orange
apple
banana
orange

このファイルに対して、そのままuniqを実行しても何も変化は起きません。

しかし、sortコマンドと組み合わせることで、すべての重複を正しく処理できます。

Shell
# sortとuniqを組み合わせて重複を削除
sort data.txt | uniq
実行結果
apple
banana
orange

このように、パイプラインを活用することで、リスト内のユニークな項目だけを抽出することが可能になります。

主要オプションによる高度な重複制御

uniqコマンドには、単に重複を消すだけでなく、データの分析に役立つ強力なオプションが多数用意されています。

実務で特によく使われる4つのオプションについて解説します。

出現回数をカウントする -c オプション

-c--count)オプションを使用すると、各行が何回連続して出現したかという回数を行頭に表示します。

これは、アクセスログの集計や、どのデータが最も多く含まれているかを調査する際に非常に役立ちます。

Shell
# 重複回数を表示
sort data.txt | uniq -c
実行結果
2 apple
1 banana
2 orange

この結果をさらにsort -rn(数字の大きい順に並べ替え)に渡すことで、出現頻度ランキングを簡単に作成できます。

重複している行のみを抽出する -d オプション

逆に、重複していない行は無視して、重複が発生している行だけを確認したい場合には-d--repeated)オプションを使用します。

このオプションは、設定ファイルやデータベースの書き出しデータにおいて、不正な重複データが混入していないかチェックする際に便利です。

Shell
# 重複がある行だけを表示
sort data.txt | uniq -d
実行結果
apple
orange

1回しか出現しなかった「banana」は除外されていることがわかります。

一度しか出現しない行を抽出する -u オプション

-u--unique)オプションは、-dとは対照的に、一度も重複しなかった行だけを表示します。

他のデータと被っていない、完全にユニークな値を探し出す際に有効な手段となります。

Shell
# 重複のない行だけを表示
sort data.txt | uniq -u
実行結果
banana

大文字と小文字を区別せずに比較する -i オプション

デフォルトでは、uniqは「Apple」と「apple」を別の行として扱います。

しかし、-i--ignore-case)オプションを使用することで、アルファベットの大小を無視して重複判定を行うことができます。

Shell
# 大文字小文字を区別せずにuniqを実行
echo -e "Apple\napple\nBANANA" | sort -f | uniq -i
実行結果
Apple
BANANA

この際、出力されるのは最初に見つかった形式の文字列となります。

特定のフィールドや文字を無視して比較する方法

データが単純な単語リストではなく、複数の列(フィールド)で構成されている場合、特定の列だけを見て重複を判断したいことがあります。

uniqにはそのような複雑な処理を可能にするオプションも備わっています。

フィールドをスキップする -f オプション

-f--skip-fields)オプションを使用すると、指定した数だけのフィールド(空白区切りの列)を無視して比較を行います。

例えば、「ID 日付 データ」という形式のファイルで、IDと日付を無視してデータ部分だけで重複を判定したい場合に利用します。

Shell
# 最初の2フィールドを無視して3列目以降で比較
uniq -f 2 sample_data.txt

この機能により、ログファイルのタイムスタンプ部分だけが異なる同一メッセージをまとめることが可能になります。

文字数をスキップする -s オプション

フィールド区切りではなく、「行頭から何文字分を無視するか」を指定したい場合は-s--skip-chars)オプションを使います。

固定長フォーマットのテキストデータを処理する際に非常に強力なツールとなります。

Shell
# 行頭の5文字を無視して比較
uniq -s 5 datafile.txt

実用的なuniqコマンドの活用例

ここでは、システム管理やデータ分析で実際に使える具体的なパイプラインの例を紹介します。

最も有名な活用例の一つは、WebサーバーのアクセスログからIPアドレスごとのアクセス数を集計することです。

Shell
# アクセスログからIPアドレス(1列目)を抽出してカウントし、多い順に並べる
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -n 10

このコマンドは、まずawkでIPアドレスのみを抽出し、sortで並べ替えた後にuniq -cで回数を集計しています。

最後に再びsort -nrで数値として降順に並べ替えることで、アクセス数トップ10のIPを特定できます。

また、プログラムの依存関係リストや、システム内のインストール済みパッケージリストから重複を削除してクリーンな状態にする際にも活用されます。

uniqコマンドのオプション一覧表

これまでに紹介した主要なオプションを以下の表にまとめました。

オプション説明
-c各行の出現回数をカウントして表示する。
-d重複している行のみを表示する(1つにまとめる)。
-u重複のない、1回だけ出現した行のみを表示する。
-i比較時に大文字と小文字の区別を無視する。
-f N行頭のN個のフィールド(空白区切り)を無視して比較する。
-s N行頭のN文字を無視して比較する。
-w N行頭のN文字分だけで比較を行う。

より柔軟な重複削除:awkによる代替案

uniqコマンドは非常に便利ですが、「事前にsortが必要である」という制約が、時にパフォーマンス上のボトルネックになることがあります。

巨大なファイルを処理する際、元の順序を維持したまま重複だけを削除したい場合は、awkコマンドを利用する手法も一般的です。

Shell
# sortせずに重複を削除(順序を維持)
awk '!a[$0]++' data.txt

このコマンドは、連想配列を利用して各行の出現回数をメモリ上で管理し、初めて現れた行だけを表示します。

ただし、メモリ消費量が増える可能性があるため、状況に応じてuniqと使い分けるのがプロのテクニックです。

まとめ

Bashのuniqコマンドは、テキスト処理において欠かすことのできない非常に強力なツールです。

基本的な重複削除だけでなく、-cオプションによる集計や、-dオプションによるエラーチェックなど、その用途は多岐にわたります。

「必ずsortコマンドとセットで使う」という基本を忘れずに、パイプラインを組み合わせることで複雑なデータ加工もコマンド一行で完結させることができます。

日々のコマンドライン操作において、今回紹介したオプションを積極的に活用し、データ処理の効率化を図ってみてください。

ログ解析やリスト作成など、あらゆる場面でuniqコマンドの利便性を実感できるはずです。

URLをコピーしました!