2012-10-03 3 views
-1

다른 차량 종류의 인벤토리를 만들려고합니다. 이 단계에서 내 데이터는awk는 두 개의 동일한 필드를 포함하는 레코드의 마지막 발생을 유지합니다.

land; road; car (blue); 1956 
land; road; car (blue); 1956 ; car (yellow); 1995 
land; road; car (blue); 1956 ; car (yellow); 1995; car (red); 1979 
air; -; plane (black); 1984 
air; -; plane (black); 1984; helicopter (red); 1998 

처음 같은 제 1 및 제 2 필드 라인의 마지막 발생을 유지할 필요가 같은

land; road; car (blue); 1956 ; car (yellow); 1995; car (red); 1979 
air; -; plane (black); 1984; helicopter (red); 1998 

을보고 존재하는 경우 그 다음 세 번째, 다섯 번째 필드를 정렬

land; road; car (yellow); 1995; car (red); 1979; car (blue); 1956 
air; -; helicopter (red); 1998; plane (black); 1984 

답변

1

편도 얻기 위해 주문 하강하여 연관된 인접 필드 (네 번째, 여섯 번째, 여덟 번째 또는 각각)와. 배열을 비우기 위해 delete 명령어를 사용하기 때문에 GNU awk이 필요합니다. 오류가 발생하면 각 키를 개별적으로 삭제하려면 for 루프를 사용해야합니다.

land; road; car (blue); 1956 
land; road; car (blue); 1956 ; car (yellow); 1995 
land; road; car (blue); 1956 ; car (yellow); 1995; car (red); 1979 
air; -; plane (black); 1984 
air; -; plane (black); 1984; helicopter (red); 1998 

그리고 awk 프로그램 script.awk에서 :

BEGIN { 
     ## Split line in ";" with spaces between it. 
     FS = "[[:space:]]*;[[:space:]]*"; 

     ## In output separate fields with a ";" followed by a space. 
     OFS = "; "; 
} 

## First line is special, save the line with its first two fields as a key of 
## a hash to check repeated ones. 
FNR == 1 { 
     keys[ $1 OFS $2 ] = $0; 
     next; 
} 

## For every line... 
{ 
     ## Extract the key (first two fields). 
     key = $1 OFS $2; 

     ## I want to get last line of each key. If it exists in the hash may be the last one, but 
     ## can't be sure until I read the next one, so save its content, read next line and wait... 
     if (key in keys) { 
       keys[ key ] = $0; 
       next; 
     } 

    ## Order and print vehicles by date :-) 
     order_and_print_vehicles_by_date(keys); 

     ## Empty the hash. 
     delete keys; 

     ## Save new kind of vehicles. 
     keys[ key ] = $0; 
} 

END { 
     order_and_print_vehicles_by_date(keys); 
} 


function order_and_print_vehicles_by_date(keys,     ordered_line, dates, vehicles) { 

     ## "keys" has only one key, get it. 
     for (k in keys) { 
       line = keys[ k ]; 
     } 

     ## Remove the key (first two fields) of the line. 
     sub(/^([^;]*;){2}[[:space:]]*/, "", line); 

     ## Get vehicles and dates from the line. 
     split(line, data, /;[[:space:]]*/); 

     ## Even positions of the array are vehicles, odd positions are for dates. Extract them. 
     for (i = length(data); i >= 1; i--) { 
       if (i % 2 == 0) { 
         dates[ ++d ] = data[ i ]; 
       } 
       else { 
         vehicles[ dates[d] ] = data[ i ]; 
       } 
     } 

     ## Sort dates in descendant order. 
     asort(dates, ordered_dates, "@val_num_desc"); 

     ## Get the line to print. 
     printf "%s%s", k, OFS; 
     for (i = 1; i <= length(ordered_dates); i++) { 
       ordered_line = ordered_line sprintf("%s%s%s%s", vehicles[ ordered_dates[i] ], OFS, ordered_dates[i], OFS); 
     } 

     ## Remove last ";" from the line and print. 
     sub(/[[:space:]]*;[[:space:]]*$/, "", ordered_line); 
     printf "%s\n", ordered_line; 
} 

실행이 좋아 : 데이터 infile 가정

awk -f script.awk infile 

그 수율 :

+0

@lqdo : 좋아. 나는 당신이 기능을 원했지만 당신의 프로그램의 모든 맥락을 모른다는 것을 읽었다. 그렇더라도, 대부분의 코드를 함수 안에 포함 시켰습니다. 'END' 섹션은 파일의 모든 입력을 읽은 후에 실행되므로 마지막 레코드를 처리하는 특별한 경우입니다. – Birei

0

나는 이것이 당신이 찾고있는 gues :

awk -F";" '{a[$1$2]=$0}END{for(i in a)print a[i]}' your_file | sort -k 2.2r -t"(" 

testetd 아래 :

> cat temp 
land; road; car (blue); 1956 
land; road; car (blue); 1956 ; car (yellow); 1995 
land; road; car (blue); 1956 ; car (yellow); 1995; car (red); 1979 
air; -; plane (black); 1984 
air; -; plane (black); 1984; helicopter (red); 1998 
air2; -; plane (black); 1984 
air2; -; plane (black); 1984; helicopter (green); 1998 
land2; road; car (blue); 1956 ; car (yellow); 1995 
land2; road; car (blue); 1956 ; car (zcar); 1995; car (red); 1979 
> nawk -F";" '{a[$1$2]=$0}END{for(i in a)print a[i]}' temp | sort -k 2.2r -t"(" 
land2; road; car (blue); 1956 ; car (zcar); 1995; car (red); 1979 
land; road; car (blue); 1956 ; car (yellow); 1995; car (red); 1979 
air; -; plane (black); 1984; helicopter (red); 1998 
air2; -; plane (black); 1984; helicopter (green); 1998 
관련 문제