2011-07-12 17 views
1

私の入力ファイルはこのようです。unixのキーに基づいて選択したレコードを並べ替える

 
01,A,34 
01,A,35 
01,A,36 
01,A,37 
02,A,40 
02,A,41 
02,A,42 
02,A,45 

私の出力は

 
01,A,37 
01,A,36 
01,A,35 
02,A,45 
02,A,42 
02,A,41 

すなわちキー(第一および第二列)に基づいてのみ、上位3つのレコード(第三列に基づいて、トップ値)事前に

感謝を選択する必要があります。 ..

答えて

2

単純なbashスクリプトを使用して、データが示されている場合は、これを行うことができます。

pax$ cat infile 
01,A,34 
01,A,35 
01,A,36 
01,A,37 
02,A,40 
02,A,41 
02,A,42 
02,A,45 

pax$ ./go.sh 
01,A,37 
01,A,36 
01,A,35 
02,A,45 
02,A,42 
02,A,41 

pax$ cat go.sh 
keys=$(sed 's/,[^,]*$/,/' infile | sort -u) 
for key in ${keys} ; do 
    grep "^${key}" infile | sort -r | head -3 
done 

最初の行はsedは、出力をソートし、sortで重複を除去すると、最終列を除去することにより、最初の2つのフィールドから構成されたキーのフルセットを取得します。この特定の場合、キーは01,A,02,A,です。

それは抽出各キー(grepと併せてforループ)に関連するデータ、sort -rで降順にソートし、headと(各キーのための)最初の3を得ます。

.[などの特殊な文字がキーに含まれている可能性が高い場合は、注意する必要があります。 Perlの

+0

名様こんにちは...優れた...ウルのコードは素晴らしい取り組んでいる...しかし、私は大きななしのセットに同じロジックを適用したとき。レコードのうち、スクリプトは記憶を言っていません...他の選択肢??? – aln

+0

@ain: 'sed 's /、[^、] * $ /、/ infile |ソート-u |読み込み中。 grep "^ $ key" infile | grepを実行します。ソート-r |ヘッド-3;完了しました。大量のレコードでは、whileループの処理はs..l ... o .... w!となります。 –

+0

@aln、それはどこに問題があるかによって異なります。あなたのファイルにいくつの行がありますか( 'wc -l infile'を使いますか?いくつのユニークなキー( 'sed 's /、[^、] * $ /、/' infile | sort -u | wc -l')を使いますか? – paxdiablo

0

perl -F, -lane' 
    push @{$_{join ",", @F[0,1]}}, $F[2]; 
    END { 
    for $k (keys %_) { 
     print join ",", $k, $_ 
     for (sort { $b <=> $a } @{$_{$k}})[0..2] 
     } 
    }' infile 
+0

ああ素晴らしいradoulov ....ありがとう...しかし、私はawkで同じを得ることができるか、より多くのレコードの世話をsedで??? – aln

+0

次のようなものを試してみてください: 'sort -t、-k1,2 -k3nr infile | awk -F、 '_ [$ 1、$ 2] ++ <3'' –

関連する問題