9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

uniqコマンドで「指定したフィールドで重複をチェック」したい

Last updated at Posted at 2020-02-20

uniq とは

uniq は、ある入力から行を読み込み、重複した行を取り除いて出力するコマンドです。 例えば以下のようなinput.txtがあったとします。

$ cat input.txt
aaa
aaa
bbb

こいつにuniqをかけると重複行(aaa)が取り除かれます。ただしあらかじめソートされている必要があります。

$ cat input.txt | uniq
aaa
bbb

やりたいこと

このようなinput2.txtがあったとします。

$ cat input2.txt
tanaka taro
tanaka ichiro
sato taro

CSV的な感じですね。スペース区切りで氏名が載っているようです。今、uniqを使って名字が重複している行を取り除き、以下のような出力を得たいとします。

$ cat input2.txt | uniq --なんらかのオプション
tanaka taro
sato taro

また、下の名前でも重複をチェックしたり、もっと言うと項目がたくさんあるCSVファイルなどで指定したフィールドでの重複チェックができたら便利そうです。

指定したフィールドで重複チェックをするオプション

さて、これをやるにはどのようなオプションをつければいいのでしょうか。マニュアルを見てみます。ありません。 結構調べたけどやっぱりないっぽい。意外。

一応、「(最大で)指定した文字数までで重複チェック」なら -w。でもこれだと一つ目の項目でしかできないし、そもそも文字数にばらつきがあると使えません。

有志によるパッチが作成されているがおそらく本家にマージはされない模様。

http://lists.gnu.org/archive/html/coreutils/2013-02/msg00016.html
http://lists.gnu.org/archive/html/coreutils/2013-02/msg00019.html

sortの-kオプションと同じものを実装したいと2006年に書いてあるがどうなっていることやら…

どうすればいいのか

ワークアラウンドとしては、awk でできます。この場合、重複行のうち残したいものが一番上にくるようにソートしたのちに以下。

awk '!colname[$1]++{print}'

input2.txtの例だとこうなります。

# 名字で重複削除
$ cat input2.txt | awk '!colname[$1]++{print}'
tanaka taro
sato taro

# 下の名前で重複削除
cat input2.txt | awk '!colname[$2]++{print}'
tanaka taro
tanaka ichiro

参考:
awkで重複行を高速削除する。 - 忘れないようにメモっとく
linux - Is there a way to 'uniq' by column? - Stack Overflow

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?