最初の3行

最初の3行

2つのファイルがあります。最初のファイルは、2番目のファイルに関心のある行を示すログファイルです(FILTER_FILEと呼びます)。ファイルに重複した行が含まれる可能性があるため、最初のファイルの各固有行に対して2番目のファイルを処理するだけです。
2番目のファイル(DATA_FILEと呼ばれる)には、ファイル1の各行に複数の行が含まれており、最初のファイルで一致する最初の3つの項目について合計する必要がある数字があります(他のファイルは無視できます) )。

私はいくつか試してみましたが、知識はawk基本にすぎません。できるだけ使い、習得しようとしています。

私がやったやや不器用な試みは次のとおりです。

awk '{print $1 " " $2}' filter_file | sort -u >> tst

while read filter; 
    do grep "$filter" data_file | head -3; done < tst >> ./short_data_file

while read line;
    do grep "$filter" short_data_file | awk '{ sum += $3 } END { print $1 " " $2 " " sum }' ; done < tst >> summary_file

フィルタファイルの例形式:

abcd 123456  
abcd 123456  
abcd 123456  
abcd 123457  
abcd 234567  
abcd 234567  
abcd 234567  
abcd 890123  
abcd 890123  
abcd 890123  
abcd 890123  
abcd 890123  
abde 344566  
abde 344566  
abde 344566 

データファイルのサンプル形式:

abcd 123456 3  
abcd 123456 4  
abcd 123456 3  
abcd 123456 56  
abcd 123456 6   
abcd 123456 1   
abcd 123457 6  
abcd 123457 4  
abcd 123457 89  
abcd 123457 3  
abcd 123457 9  
abcd 234567 5  
abcd 234567 3  
abcd 234567 8   
abcd 234567 6  
abcd 234567 76  
abcd 234567 34  
abcd 234567 0  
abcd 234567 7  
abcd 890123 5  
abde 344566 152  

編集:上記のデータファイルから生成された出力です。

abcd 123456 10  
abcd 123457 99  
abcd 234567 16  
abcd 890123 5  
abde 344566 152   

編集:実際の実際のデータファイルは、フィルタファイルの場合は数千、データの場合は数百万に達します。

ベストアンサー1

努力する

awk 'NR == FNR { data[$1 " " $2]=0 ; next ; }
{ if ($1 " " $2 in data) data[$1 " " $2]+=$3 }
 END { for ( d in data ) printf "%s %d\n",d,data[d] ;} ' filter data

(一行で可能です)

どこ

  • NR == FNR { data[$1 " " $2]=0 ; next ; }フィルタファイルに行を保存する
  • { if ($1 " " $2 in data) data[$1 " " $2]+=$3 }データに 3 番目の列の値を追加する場合
    • END { for ( d in data ) printf "%s %d\n",d,data[d] ;}合計を印刷する

出力順序はランダムなので、パイプを介してsort

最初の3行

これは修正されたawkです。

NR == FNR { countit[$1 " " $2]=0 ; next ; }
{ if ($1 " " $2 in countit) {
    data[$1 " " $2]+=$3 ;
    countit[$1 " " $2] ++ ;
    if ( countit[$1 " " $2] == 3 ) {
            printf "%s %s %s\n",$1,$2,data[$1 " " $2] ;
            delete data[$1 " " $2] ;
            delete countit[$1 " " $2] ;
    }
    }
}

 END { for ( d in data ) printf "%s %d\n",d,data[d] ;}

不完全なリスト(1つまたは2つの要素など)を処理する方法によっては、END行を削除できます。

おすすめ記事