ヒント: uniqを使って、重複する行を削除する

textutilsを知ろう

Comments

並べ換えを行うと、重複している行が見つかることがあります。このような情報の重複は不要で、ディスク・スペースの節約のために削除してもかまわないときがあります。テキストは、並べ換えられている必要はありませんが、uniq は、読み出しを行いながら行を比較し、連続する2行以上を削除するだけであることに注意してください。以下の例は、このツールがどんな働きをするのかを示したものです。

リスト1. uniqを使って重複する行を削除する
$ cat happybirthday.txt
Happy Birthday to You!
Happy Birthday to You!
Happy Birthday Dear Tux!
Happy Birthday to You!

$ sort happybirthday.txt
Happy Birthday Dear Tux!
Happy Birthday to You!
Happy Birthday to You!
Happy Birthday to You!

$ sort happybirthday.txt | uniq
Happy Birthday Dear Tux!
Happy Birthday to You!

経理データなど重要なデータの入ったファイルでuniq などのツールを使って重複行を削除するのは危険ですので、警告しておきます。そういうファイルで行が重複しているのは、ほとんどが、同じ金額の別の取引を表している場合であり、それを削除すると、経理部でいろいろな問題を起こしてしまうことになります。絶対にそんなことを行ってはいけません。

もっと簡単に、1行しかない行 (unique lines) だけ、あるいは重複のある行 (duplicate lines) だけを表示させたい場合は、どうでしょうか。それには、以下のように、-u (unique) オプション、-d (duplicate) オプションを指定します。

リスト2. -uオプション、-dオプションの使い方
$ sort happybirthday.txt | uniq -u
Happy Birthday Dear Tux!

$ sort happybirthday.txt | uniq -d
Happy Birthday to You!

uniq-c オプションを添えると、統計を表示させることもできます。

リスト3. -cオプションの使い方
$ sort happybirthday.txt | uniq -uc
1 Happy Birthday Dear Tux!

$ sort happybirthday.txt | uniq -dc
3 Happy Birthday to You!

uniq が行全体を比較するものであっても便利なのでしょうが、このコマンドの機能は、それで終わりというわけではありません。とくに便利なのが、指定した数のフィールドを飛ばす機能で、それには、-f オプションに続けて飛ばしたいフィールドの数を指定します。これは、システム・ログを眺める場合に非常に役に立ちます。いくつかのエントリーが何度も重複しているというのはよくあることで、これがログを調べにくくしています。どのエントリーもタイムスタンプが違っていますので、ただ単にuniq を使っても用をなしません。しかし、時刻フィールドをすべて飛ばすように指定してやると、とたんに、ログは扱いやすくなります。uniq -f 3 /var/log/messages を試してみて、結果を自分で確認してみてください。

他に、-f と同じような働きで、指定した文字数だけ飛ばす-s オプションというのもあります。-f-s を組み合わせて使用することもできます。その場合、uniq は、まずフィールドを飛ばし、次に文字を飛ばします。逆に、指定した文字数だけで比較を行いたい場合はどうでしょうか。-w オプションを使ってみてください。

質問やご意見のある方は、ぜひお聞かせください。jacek@artymiak.com までメールをいただければ幸いです。

次回は、nl を取り上げる予定です。それでは、また。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux, Open source
ArticleID=231476
ArticleTitle=ヒント: uniqを使って、重複する行を削除する
publish-date=04032003