uniqで特定のフィールドに対して重複するものを除去するには、
オプション -f と -w を使えばよい。
フィールドは、スペースかタブで区切られた文字列。
-wは比較に使用するフィールドのバイト数。
-fが行頭から順に取り除くフィールドの数。
取り除いたフィールドとその次のフィールドとの間のスペースまたはタブは取り除かれない。
そのため、-wと組み合わせるときは、-wのバイト数の計算に注意が必要である。
[a.txt] 11 abc ABC 12 abc xXx 234 abb XXX 456 bbb XXX 234 bbbc YYY
2個目のフィールドの重複を取り除くには、
$ uniq -f1 -w5 a.txt 11 abc ABC 234 abb XXX 456 bbb XXX 234 bbbc YYYとする。-w5は、a.txtの5行目の2番目のフィールドとその直前のセパレータを合わせたバイト数が5であるため。
uniqではフィールド幅が可変長のフィールドの重複除去は行いにくい。
仮に-w6にすると、
$ uniq -f1 -w6 a.txt 11 abc ABC 12 abc xXx 234 abb XXX 456 bbb XXX 234 bbbc YYYのようになる。これは、比較に使用される文字が
abc A abc x abb bbb X bbb cとなるため(行頭にスペースが1個入っていることに注意)。
したがって、
[b.txt] 11 abc ABC 12 abc DEF 13 abcd xXx 14 abcde XXX 15 abcde YYYに対して、2番目のフィールドで重複除去をしようとしても、
$ uniq -f1 -w6 b.txt 11 abc ABC 12 abc DEF 13 abcd xXx 14 abcde XXXのようになってしまう。これを避けるには、対象とするフィールドを
行末にコピーしてuniqを行ったあと、それを除去すればよい。
例えば、
$ awk '{print $0" "$2}' b.txt | uniq -f3 | sed 's/ [[:graph:]]*$//' 11 abc ABC 13 abcd xXx 14 abcde XXXのようにする。
日本語も処理できるが、-wがバイト数のため指定しにくい。
[c.txt (UTF-8)] 11 abc ABC 12 abc DEF 13 あさ xXx 14 あさ XXX 15 あみ YYY
例えば、2番目のフィールドの幅を4バイトとすると、
$ uniq -f1 -w4 c.txt 11 abc ABC 13 あさ xXxとなり、「あ」しか比較対象にならない。
なので、
$ awk '{print $0" "$2}' c.txt | uniq -f3 | sed 's/ [[:graph:]]*$//' 11 abc ABC 13 あさ xXx 15 あみ YYYのように、後ろに移動させてからuniqするのが簡単。