2017-10-07 12 views
-1

出現回数で入力を並べ替える必要があります。しかし、私は一意または非一意の行を削除したくありません。私は出力以下であろうと、パイプラインコマンドのセットを探していると思いますどのように外観の数で行をソートするのですか?UNIX?

Not unique 
This line is unique 
Not unique 
Also not unique 
Also unique 
Also not unique 
Not unique 

This line is unique 
Also unique 
Also not unique 
Also not unique 
Not unique 
Not unique 
Not unique 

はあなたが提供することができます任意の助けてくれてありがとうたとえば私は、次の入力を与えた場合私は、ユニークとソートのさまざまな組み合わせを使用しようとしてきましたが、それを理解することはできません。ソリューションは、好ましくは1つのライナーになります。

更新:私がよく知っていたコマンドで探していたのは、特にバットマンの方に感謝します。

私はまだ一見単純なタスクのために複数のコマンドをパイプラインして使用する方法を学んでいますので、2列で作業するように彼の答えを適応させることは可能でしょうか?たとえば、元の入力があった場合:

Notunique dog 
Thislineisunique cat 
Notunique parrot 
Alsonotunique monkey 
Alsounique zebra 
Alsonotunique beaver 
Notunique dragon 

そして、私はそうのように最初の列でソートされるように、出力を望んでいた:

Thislineisunique cat 
Alsounique zebra 
Alsonotunique monkey 
Alsonotunique beaver 
Notunique dog 
Notunique parrot 
Notunique dragon 

は、事前にそれほど有用であることありがとうございました!

+0

あなたが持っているものを表示することができますこれまでに試しましたか?私は 'collections.Counter'を使ってかなり短いことができる短いPythonスクリプトを使いますが、これは純粋な' shell'ソリューションではうまくいかないでしょう。 – norok2

答えて

0

uniq + sort + grep溶液:

inputfile

拡張内容:

Not unique 
This line is unique 
Not unique 
Also not unique 
Also unique 
Also not unique 
Not unique 
Also not unique 
Also not unique 

は、予め初期ファイルをソート:

sort inputfile > /tmp/sorted 

uniq -u /tmp/sorted; uniq -dc /tmp/sorted | sort -n | cut -d' ' -f8- \ 
    | while read -r l; do grep -x "$l" /tmp/sorted; done 

出力:

Also unique 
This line is unique 
Not unique 
Not unique 
Not unique 
Also not unique 
Also not unique 
Also not unique 
Also not unique 

----------

あなたはまた、bashスクリプトにジョブ全体を囲むことがあります。

#!/bash/bash 

sort "$1" > /tmp/sorted # $1 - the 1st argument (filename) 
uniq -u /tmp/sorted 

while read -r l; do 
    grep -x "$l" /tmp/sorted 
done < <(uniq -dc /tmp/sorted | sort -n | cut -d' ' -f8-) 
+0

これは外観の数でソートせず、一意の線(ソート済み)を最初に配置し、非固有線は頻度ではなくアルファベット順にソートします。もしも入力にもう一度 'Not also unique'という行がある場合は、出力の最後に表示されるはずですが、この解決策ではありません。 –

+0

これを入力ファイルとして使用してください。それぞれの文字は、別々の行にあります。 'A A B B B B C C C'。明らかに、頻度別にソートすると、これは「A A C C B B B B」になるか、または「B B B B C C C A A」になるようにソートされなければなりません。 'uniq'は入力を並べ替えず、ただフィルタリングします。 –

+0

@BenjaminW。、ok、私の更新を確認してください – RomanPerekhrest

0

私は、各行が発生した回数をカウントし、それらをプリントアウトするawkを使用し(周波数によって事前保留)とソート数値sort -nを使用します:

awk 'FNR==NR{freq[$0]++; next} {print freq[$0],$0}' data.txt data.txt | sort -n 

サンプル出力

1 Also unique 
1 This line is unique 
2 Also not unique 
2 Also not unique 
3 Not unique 
3 Not unique 
3 Not unique 

それは本当にシュワルツァー変換です。先頭の周波数列を破棄したい場合は、コマンドの最後に| cut -d ' ' -f 2-を追加するだけです。

1

awkだけが最新の質問に最適です。

$ awk '{file[$0]++; count[$1]++; max_count= count[$1]>max_count?count[$1]:max_count;} END{ k=1; for(n=1; n<=max_count; n++){ for(i in count) if(count[i]==n) ordered[k++]=i} for(j in ordered) for(line in file) if (line~ordered[j]) print line; }' file 

Alsounique zebra 
Thislineisunique cat 
Alsonotunique beaver 
Alsonotunique monkey 
Notunique parrot 
Notunique dog 
Notunique dragon 

説明:

パート1:

{file[$0]++; count[$1]++; max_count= count[$1]>max_count?count[$1]:max_count;}

我々はfile配列で入力ファイルを格納しています。 count配列は、ファイルをソートするために必要な、一意の最初の各フィールドのカウントを追跡します。 max_countは最大カウントを追跡します。

パート2: awkはファイルの読み込みが終了したら、countの内容は、次のようになります:(キー、値)

Alsounique 1 
Notunique 3 
Thislineisunique 1 
Alsonotunique 2 

は、今私たちの目的は値によってこれらのキーを並べ替えることです示すように、以下。これは我々のキーステップです。以下の出力では、それぞれのフィールド/キー/カラム1に対して、file配列を反復処理し、これらのキーを含む行を出力して、最終的な出力を得られます。ループ下

Alsounique 
Thislineisunique 
Alsonotunique 
Notunique 

sorted by values様式でorderedと呼ばれる別の配列にcountアレイのコンテンツを格納する動作を行います。 orderedの内容は、上記の出力と同じです。

for(n=1; n<=max_count; n++) 
    { 
     for(i in count) 
      if(count[i]==n) 
      ordered[k++]=i 
    } 

最終工程:すなわちfileにわたる配列を反復し、orderedアレイに格納されているフィールドの順に行を印刷します。

for(field in ordered) 
    for(line in file) 
     if (line~ordered[field]) 
      print line; 
    } 

は、溶液2:他の可能な解決策は、ソートUNIQAWKを使用することになる
/
を切りました。しかし、複数のパイプが複数のプロセスを呼び出して操作全体を遅くするため、入力ファイルが非常に大きい場合は、これを使用することをお勧めしません。

$ cut -d ' ' -f1 file | sort | uniq -c | sort -n | awk 'FNR==NR{ordered[i++]=$2; next} {file[$0]++;} END{for(j in ordered) for(line in file) if (line~ordered[j]) print line;} ' - file 
Alsounique zebra 
Thislineisunique cat 
Alsonotunique beaver 
Alsonotunique monkey 
Notunique parrot 
Notunique dog 
Notunique dragon 

前の溶液(OP編集前に質問)

は、これは、このようsortuniqawkを使用して行うことができます

$ uniq -c <(sort f1) | sort -n | awk '{ for (i=1; i<$1; i++){print}}1' 
     1 Also unique 
     1 This line is unique 
     2 Also not unique 
     2 Also not unique 
     3 Not unique 
     3 Not unique 
     3 Not unique 
+0

ありがとう、これは私が探していたものとまったく同じです!私はまだ一見単純なタスクのために複数のコマンドをパイプライン化して使用する方法を学ぼうとしていますので、これを2列で動作させることは可能でしょうか?例えば、元の入力は 一意でない Alsonotunique 6 5 Alsounique 4 Alsonotunique 3 Notunique 2 Thislineisunique 1 Notuniqueていたと私は出力がそう Thislineisunique 2 等最初の列でソートすることがしたい場合Alsounique 5 Alsonotunique 4 Alsonotunique 6数値は単なるテキスト – trysofter

+0

を表す7 Notunique 1 Notunique 3 Notunique以前のコメントは、Iであるので、私は、元の投稿を編集nより良いフォーマット、もう一度ありがとう! – trysofter

+0

あなたのアプローチでは第1列が冗長です – RomanPerekhrest

関連する問題