다대일 관계가 있는 두 개의 열을 기반으로 데이터를 필터링하려면 awk를 사용해야 합니다.

다대일 관계가 있는 두 개의 열을 기반으로 데이터를 필터링하려면 awk를 사용해야 합니다.

|로 구분된 50개의 열과 100,000개의 행이 있는 대용량 파일이 있습니다. 이제 $2(col 2)에는 $1(col 1)에 대해 여러 유형의 값이 있으며 이는 col 2가 반복된다는 의미입니다. 그래서 파일을 정리했습니다. 이제 다음을 기준으로 결과 파일을 추출/필터링해야 합니다. $1은 열 1 $2는 열 2

$2와 $1 사이에는 일대다 관계가 있습니다.

조건 1: $2에 $1의 두 가지 유형이 있는 경우($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: 두 번째 필드를 기준으로 정렬한 다음 첫 번째 필드를 기준으로 정렬합니다.
  • |정렬된 줄은 줄의 마지막 문자여야 합니다.
  • $1 < 8000 { a[$2]++ ; print }8000 미만이면 줄을 인쇄하고 $2 값을 기억하세요.
  • $1 >= 8000 { ... }높을 경우 가장 높은 값을 저장
  • END { for ( i in u ) print u[i] ;}종료 시 모든 값 덤프

  • 다시 주문해야 할 수도 있습니다.

  • 2행 조건을 단순화할 수 있습니다(if 조건을 {} 외부에 배치하여).

  • 테스트의 일부 행에는 9개의 필드가 있습니다.

명령은 한 줄일 수 있습니다.

... | sort -n -t\| -k2 -k1  | awk -F\| '...'

관련 정보