2010-06-29 2 views
1

임의로 배열 된 여러 필드가있는 다양한 입력 파일을 처리해야하지만 일관되게 이름이 지정되고 헤더 행으로 레이블이 지정됩니다. 이러한 파일은 관련 필드가 모두 제거되고 누락 된 필드가 차지하는 등 원하는 모든 필드가 특정 순서로 재구성되어야합니다. 과거에 필드 관련 딜레마 테이션을 처리 할 때 너무 잘 해줬 기 때문에 AWK을 사용하기를 바랬습니다. 잘 작동 AWK를 사용하여 명명 된 필드 재구성

# imagine a perfectly-functional BEGIN {} block here 

NR==1 { 
    fldname[1] = "first_name" 
    fldname[2] = "last_name" 
    fldname[3] = "middle_name" 
    maxflds = 3 

    # this is just a sample -- my real script went through forty-odd fields 

    for (i=1;i<=NF;i++) for (j=1;j<=maxflds;j++) if ($i == fldname[j]) fldpos[j]=i 
} 

NR!=1 { 
    for (j=1;j<=maxflds;j++) { 
    if (fldpos[j]) printf "%s",$fldpos[j] 
    printf "%s","/t" 
    } 
    print "" 
} 

지금이 솔루션 : 주위에 비료를 조금 후

, 나는 훨씬 다음 (메모리에서 작성, 검증되지 않은) 같은 것을 함께했다. 나는 그것을 실행, 내 출력을 정확히 내가 원하는 방식으로 얻을. 거기에 불만이 없습니다. 그러나 3 개 필드 이상 (예 : 40 개 필드로 작업해야했던 필드)의 경우에는 항상 고통스럽고 중복 된 코드가 많아서 항상 나를 귀찮게 할 것입니다. 그리고 다른 곳에 필드를 삽입해야한다는 생각 때문에 저를 떨리게 만듭니다.

나는 그것을 볼 때마다 조금씩 죽는다.

더욱 세련된 솔루션이 있어야합니다. 그렇지 않은 경우, 아마도 이런 종류의 작업에 더 적합한 도구가있을 것입니다. AWK은 자신의 도메인이 멋지 긴하지만, 나는 이것에 대해 한계가있다.

어떤 통찰력이라도 있습니까?

답변

0

내가 생각할 수있는 유일한 제안은 초기 배열 설정을 BEGIN 블록으로 옮기고 루프의 별도 템플릿 파일에서 정렬 된 필드 이름을 읽는 것입니다. 그러면 awk 프로그램은 내장 된 데이터가없는 루프만으로 구성됩니다. 외부 템플릿 파일은 간단한 줄 바꿈으로 구분 된 목록입니다.

BEGIN {while ((getline < "fieldfile") > 0) fldname[++maxflds] = $0} 

물론 지금과 같은 방식으로 헤더 행을 읽을 수 있습니다. 그러나 연관 배열을 사용하고 중첩 된 for 루프를 단일 for 루프로 줄이는 것이 가능합니다. 같은 뭔가 (테스트되지 않은) :

BEGIN {while ((getline < "fieldfile") > 0) fldname[$0] = ++maxflds} 

NR==1 { 
    for (i=1;i<=NF;i++) fldpos[i] = fldname[$i] 
} 
+0

내가 연관 배열의 아이디어를 좋아하지만,이 배열의 순서를 보장 할 청소 방법은 없습니다 AFAIK 동안 인쇄, 따라서 (처음부터 더 둔한를 정렬 기능을 작성하지 못 없음 asort, 불행하게도). 나는 그것을 인쇄하는 동안 루프를 통해 정수 키를 제공하기 때문에'fldpos [fldname [$ i]] = i'가 헤더 루프에서 작동 할 수 있다고 생각하고 있습니다 ... – goldPseudo

+0

@ goldPseudo : 나는 생각하지 않았습니다. 그것에 대해. 나는 네 생각이 효과가 있다고 생각해. –

관련 문제