처음 3줄

처음 3줄

2개의 파일이 있습니다. 첫 번째 파일은 두 번째 파일에서 관심 있는 행을 알려주는 로그 파일입니다(FILTER_FILE이라고 부르겠습니다). 파일에 중복된 줄이 포함될 수 있으므로 첫 번째 파일의 각 고유 줄에 대해 두 번째 파일을 처리하면 됩니다.
두 번째 파일(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 }데이터에 세 번째 열의 값을 추가하는 경우
    • 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 줄을 제거할 수 있습니다.

관련 정보