awk: "field-2 - field-3" 차이가 가장 작은 각 field-1 값(다름)에 대해 한 줄을 인쇄합니다.

awk: "field-2 - field-3" 차이가 가장 작은 각 field-1 값(다름)에 대해 한 줄을 인쇄합니다.

인쇄 시 미세한 차이로 선을 구분하고 싶습니다. (차이=$2-$3)

입력 파일은 다음과 같습니다.

c1,5,2         <-- diff=3
c1,5,3         <-- diff=2
c1,5,1         <-- diff=4
c2,8,3         <-- diff=5
c2,8,4         <-- diff=4

예상되는 출력은 다음과 같습니다.

c1,5,3  
c2,8,4  

awk를 사용하여 이를 어떻게 수행할 수 있습니까(예: 코드 한 줄 사용)?


즉, 각 첫 번째 필드 값(c1, c2)에 대해 첫 번째 필드 값이 포함된 단일 행을 인쇄하려고 합니다. 이는 선택된 두 번째 필드와 세 번째 필드 간의 최소 차이입니다.

답변1

즐기다해결책:

awk -F, '{ diff=$2-$3; if(a[$1]>diff || !a[$1]) { a[$1]=diff; b[$1]=$2 FS $3 } }
         END{ for(i in a) print i,b[i] }' OFS=',' yourfile

산출:

c1,5,3
c2,8,4

답변2

Awk 명령을 두 번 실행하십시오. 매우 지저분합니다.

awk -F, 'FNR == NR {diff[NR] = $2-$3;
         if (!($1 in minline) || diff[NR] < diff[minline[$1]]) {
           minline[$1]=NR}; next}
         FNR == 1 {for (a in minline) {p[minline[a]]}}
         FNR in p' file.csv file.csv

흥미롭게도 SQL을 사용하여 이 작업을 수행하는 방법은 다음과 같습니다(특히 Postgres에서 수행됨).

vagrant=# \d quick 
   Table "pg_temp_2.quick"
 Column |  Type   | Modifiers 
--------+---------+-----------
 f1     | text    | 
 f2     | integer | 
 f3     | integer | 

vagrant=# select * from quick;
 f1 | f2 | f3 
----+----+----
 c1 |  5 |  2
 c1 |  5 |  3
 c1 |  5 |  1
 c2 |  8 |  3
 c2 |  8 |  4
(5 rows)

vagrant=# select f1, f2, f3 from (select *, rank() over (partition by f1 order by f2 - f3) from quick) as x where rank = 1;
 f1 | f2 | f3 
----+----+----
 c1 |  5 |  3
 c2 |  8 |  4
(2 rows)

vagrant=# 

관련 정보