多対一の関係を持つ2つの列に基づいてデータをフィルタリングするには、awkを使用する必要があります。

多対一の関係を持つ2つの列に基づいてデータをフィルタリングするには、awkを使用する必要があります。

| で区切られた 50 個の列と 100,000 行の大容量ファイルがあります。これで、$ 2(col 2)には$ 1(col 1)に対してさまざまな種類の値があり、これはcol 2が繰り返されることを意味します。だからファイルをクリーンアップしました。ここで、以下に基づいて結果ファイルを抽出/フィルタリングする必要があります。 $ 1は列1 $ 2は列2

$2と$1の間には1対多の関係があります。

条件 1: $2 に $1 の 2 つのタイプがある場合 ($2 の $1 値は 8000 より大きく 8000 未満)、$1 < 8000 の $2 の行全体 (2 列) を選択します。

条件2:$ 2に$ 1> = 8000しかない場合は、$ 1が指定された$ 2(列2)から最小の行である行全体を選択します。例:ソースファイルの下の例では、$ 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

アドバイスしてください。よろしくお願いします。

ベストアンサー1

試してみてください(あなたはあなたのファイルです)

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:2番目のフィールドでソートし、最初のフィールドでソートします。
  • |ソートされた行は行の最後の文字でなければなりません。
  • $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\| '...'

おすすめ記事