ファイル内の重複する行を見つけて、各行が重複した回数を数えますか?


529

次のようなファイルがあるとします。

123 
123 
234 
234 
123 
345

「123」が重複した回数、「234」が重複した回数などを調べたいので、理想的には次のような出力になります。

123  3 
234  2 
345  1

4
何語を使いたいですか?
VMAtm 2011

回答:


791

1行に1つの数値があると仮定します。

sort <file> | uniq -c

--countLinuxバージョンなどのGNUバージョンでは、より詳細なフラグも使用できます。

sort <file> | uniq --count

3
これは私がやっていることですが、アルゴリズム的にはこれは最も効率的なアプローチではないようです(O(n log n)* avg_line_lenここで、nは行数です)。私は数ギガバイトのファイルに取り組んでいるので、パフォーマンスが重要な問題です。O(n)* avg_line_lenでトリックを実行する必要がある、接頭辞ツリー(私の場合、文字列には多くの場合、共通の接頭辞が含まれることが多い)を使用して、単一パスでカウントのみを行うツールがあるかどうか疑問に思います。誰かがそのようなコマンドラインツールを知っていますか?
Droggl 2013年

21
追加のステップは、その出力を最後の「sort -n」コマンドにパイプすることです。これにより、行が最も頻繁に発生する順に結果がソートされます。
samoz 2014年

79
重複する行のみを印刷する場合は、 'uniq -d'を使用します
DmitrySandalov

6
あなたは再びソート結果にしたい場合は、使用することsortのように再び:sort <file> | uniq -c | sort -n
アビシェークカシャップ

413

これは、重複した行のみをカウントし、印刷します:

sort FILE | uniq -cd

または、GNUロングオプションを使用します(Linuxの場合):

sort FILE | uniq --count --repeated

上のBSDとOSXあなたはgrepを使用する必要が独自のラインアウトフィルタ:

sort FILE | uniq -c | grep -v '^ *1 '

この例では、結果は次のようになります。

  3 123
  2 234

一度だけ現れるものを含むすべての行のカウント印刷したい場合:

sort FILE | uniq -c

または、GNUロングオプションを使用します(Linuxの場合):

sort FILE | uniq --count

指定された入力の出力は次のとおりです。

  3 123
  2 234
  1 345

最も頻度の高い行を先頭にして出力並べ替えるには、次のようにします(すべての結果を取得するため)。

sort FILE | uniq -c | sort -nr

または、重複する行のみを取得するには、最も頻繁に最初に:

sort FILE | uniq -cd | sort -nr

OSXとBSDでは、最後は次のようになります。

sort FILE | uniq -c | grep -v '^ *1 ' | sort -nr

1
--repeatedまたは-dオプションの良い点。「| grep 2」などを使用するよりもはるかに正確です。
ラウリ

このコマンドを変更して、繰り返し数が100を超えるすべての行を取得するにはどうすればよいですか?
Black_Rider 2013年

@Black_Rider パイプに| sort -nまたは| sort -nrを追加すると、繰り返しカウント(それぞれ昇順または降順)で出力がソートされます。これはあなたが求めていることではありませんが、役立つかもしれないと思いました。
Andrea

1
@Black_Rider awkはあらゆる種類の計算を実行できるようです。あなたの場合、あなたは実行できます| awk '$1>100'
Andrea

4
@fionbio OSX uniqでは-cと-dを一緒に使用できないようです。ご指摘ありがとうございます。あなたはできるユニークな行をフィルタリングするためにはgrepを使用sort FILE | uniq -c | grep -v '^ *1 '
アンドレア・

72

複数のファイルで重複する行を見つけてカウントするには、次のコマンドを試してください。

sort <files> | uniq -c | sort -nr

または:

cat <files> | sort | uniq -c | sort -nr

30

経由

awk '{dups[$1]++} END{for (num in dups) {print num,dups[num]}}' data

awk 'dups[$1]++'コマンド、変数は$1COLUMN1の全内容を保持し、角括弧は、配列アクセスです。したがって、dataファイルの行の最初の列ごとに、指定された配列のノードdupsがインクリメントされます。

そして最後に、変数dupsnumとして配列をループし、保存された数値を最初に出力してから、によって複製された値の数を出力しdups[num]ます。

入力ファイルの一部の行の終わりにスペースがあることに注意してください。それらをクリアすると、上記のコマンドの$0代わりに使用できます$1:)


1
私たちが持っていることを考えると、これは少しやりすぎではありuniqませんか?
Nathan Fellman 2016

9
sort | uniqまた、awkソリューションでは、パフォーマンスとリソースのトレードオフが大きく異なります。ファイルが大きく、異なる行数が少ない場合、awkソリューションの方がはるかに効率的です。それは行数で線形であり、スペース使用量は異なる行数で線形です。OTOH、awkソリューションはすべての異なる行をメモリに保持する必要がありますが、(GNU)ソートは一時ファイルに頼ることができます。
Lars Noschinski、2017

14

「Windows PowerShell」を使用するWindowsでは、以下のコマンドを使用してこれを実現しました

Get-Content .\file.txt | Group-Object | Select Name, Count

また、where-objectコマンドレットを使用して結果をフィルタリングすることもできます

Get-Content .\file.txt | Group-Object | Where-Object { $_.Count -gt 1 } | Select Name, Count

ファイルのソート順を変更せずに、最後の重複を除くすべての重複を削除できますか?
jparram 2017年

6

標準のUnixシェルまたはcygwin環境、あるいはその両方にアクセスできると仮定します。

tr -s ' ' '\n' < yourfile | sort | uniq -d -c
       ^--space char

基本的に:すべてのスペース文字を改行に変換し、変換された出力を並べ替えてuniqにフィードし、重複する行を数えます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.