|で区切られた50の列と100Kの行を持つ大きなファイルがあります。これで、$ 2(列2)には複数のタイプの$ 1(列1)値があり、列2が繰り返されることを意味します。だから私はファイルをソートしました。以下の条件に基づいて結果ファイルを抽出/フィルタリングする必要があります。$ 1は列1、$ 2は列2です。
2ドルから1ドルの間に1対多の関係船があります
条件1:$ 2のタイプが両方とも$ 1の場合($ 2の$ 1の値が8000を超え、8000未満の場合)、指定された$ 2に対して$ 1 <8000である行全体を選択します(列2)
条件2:$ 2に$ 1> = 8000しかない場合は、指定された$ 2(列2)に対して$ 1が最小である行全体を選択します。例:ソースファイル次の例では、3種類の$ 2(1234,123&456)があります。これで、1234の列1に3種類の値($ 1)があり、8000よりも大きいことと小さいことを意味します。したがって、$ 1 <8000の値に対して完全な行を選択しました。
123と465の場合、列1の値は8000($ 1> 80000)よりも大きいため、(列8の値が高いことに基づいて)最新の行を選択しました。
サンプルファイル
4000|1234||||||23
5000|1234||||||40
9000|1234||||||25
10000|123|||||||21
9000|123|||||||22
22000|456|||||||27
15000|456|||||||29
結果ファイルは次のようになります。
4000|1234||||||23
5000|1234||||||40
9000|123|||||||22
15000|456|||||||29
アドバイスを下さい。前もって感謝します。
試してみてください(uはあなたのファイルです)
_sort -n -t\| -k2 -k1 < u |
awk -F\| '$1 < 8000 { a[$2]++ ; print }
$1 >= 8000 { if ( !a[$2] && ( !e[$2] || e[$2]<$8 )) {u[$2]=$0;e[$2]=$8;} ; }
END { for ( i in u ) print u[i] ;}'
_
与える
_4000|1234||||||23
5000|1234||||||40
15000|456||||||29
9000|123||||||22
_
どこ
-t\|
_と_-F\|
_は、sortとawkに_|
_を区切り文字として使用するように指示します-k2
_ _-k1
_:秒で並べ替え、次に最初のフィールド|
_は、行の最後の文字である必要があります$1 < 8000 { a[$2]++ ; print }
_ 8000未満の場合は、行を印刷し、$ 2の値を覚えておいてください$1 >= 8000 { ... }
_上記の場合、最高値を保存しますEND { for ( i in u ) print u[i] ;}
終了時に、すべての値をダンプします
再ソートが必要になる場合があります。
2行目の条件を簡略化できます(ifの条件を{}の外に置くことで)
テストの一部の行には9つのフィールドがあります。
コマンドは1行にすることができることに注意してください
_... | sort -n -t\| -k2 -k1 | awk -F\| '...'
_