web-dev-qa-db-ja.com

重複の最初のインスタンスを保持する

複数の列を持つファイルがあり、bashスクリプトを使用して特定の列の値(列3〜6)が複製されている行を特定しました。

入力例:

A B C D E F G
1 2 T TACA A 3 2 Q
3 4 I R 8 2 Q
9 3 A C 9 3 P
8 3 I R 8 2 Q

繰り返し値の両方のインスタンスを表示できます。他の列の値(列1、2、7+)は2行で異なる可能性があるため、両方のインスタンスを表示する必要があります。

これらの重複を並べ替えた後、一意のレコードと複製されたレコードの最初のインスタンスをcol 5(任意の順序で実行)、次にcol 1(降順->最大値が最初)で保存したいと思います。

必要な出力:

A B C D E F G
1 2 T TACA A 3 2 Q
9 3 A C 9 3 P
8 3 I R 8 2 Q

NB:最終出力の順序は後で並べ替えられるため重要ではありません。必要な行が存在することを確認することが重要です。

これまでの私のコードは:

tot=$(awk 'n=x[$3,$6]{print n"\n"$0;} {x[$3,$6]=$0;}' oldfilename | wc -l)  #counts duplicated records and saves overall count as $tot
if [ $tot == "0" ] 
then
    awk '{print}' oldfilename >> newfilename  #if no dups found, all lines saved in new file
else if
    awk '(!(n=x[$3,$6]{print n"\n"$0;} {x[$3,$6]=$0;})' oldfilename >> newfilename  #if dups found, unique lines in old file saved in new file
else
    awk 'n=x[$3,$6]{print n"\n"$0;} {x[$3,$6]=$0;}' oldfilename > tempfile  #save dups in tempfile
    sort -k1,1, -k5,5 tempfile  #sort tempfile on cols 1 then 5 (want descending order)                  
fi

私ができないことは、各複製の最初のインスタンスを取得してそれをnewfileに保存することです。それでも上記のコードにエラーがあります。

助けてください。

5
Bob

sort自体で十分です。まず、行がフィールド範囲3-6で「グループ化」され、各グループ内のレコードがフィールド51でさらに並べ替えられるように並べ替えます。これをsort -u3-6にパイプします。これにより、最後のリゾート比較が無効になり、各3-6グループの最初のレコードが返されます。最後に、これをsortにパイプします。今回はフィールド51を使用します。

sort -k3,6 -k5,5r -k1,1r file | sort -k3,6 -u | sort -k5,5r -k1,1r
A B C D E F G
1 2 T TACA A 3 2 Q
9 3 A C 9 3 P
8 3 I R 8 2 Q
5
iruvar

私があなたを正しく理解していれば、これで十分でしょう:

$ sort input | uniq -f 2
1 2 T TACA A 3 2 Q
3 4 I R 8 2 Q
9 3 A C 9 3 P
A B C D E F G

-f 2スイッチは、最初の2つのフィールドの比較をスキップするようにuniqに指示します。したがって、重複する3つの最後のフィールドの最初のインスタンスが保持されます。

1
terdon