배열의 gawk 배열에서 문자열을 인덱스로 사용할 수 있습니까?

배열의 gawk 배열에서 문자열을 인덱스로 사용할 수 있습니까?

이 파일을 살펴보겠습니다.

9=foo 3=bar 84=baz 30=bin 71=bon
9=goo 3=gar 84=gaz 30=gin 71=gon
9=soo 3=sar 84=saz 30=sin 71=son

이 gawk 라인을 실행하십시오.

gawk '
{
    split($0,arr)
    for(i=1;i<=length(arr);i++){
        eq=index(arr[i],"=")
        num=substr(arr[i],eq+1)
        val=substr(arr[i],0,eq-1)
        printf "%s=%s ", num,val
        arr2[i][num] = val
    }
    printf ORS
}
END{
    print "---\n",arr2[2][9]}
' newfile.txt

내가 얻을 것으로 예상되는 것은 goo배열의 첫 번째 인덱스가 두 번째 행이고 두 번째 인덱스가 기호 앞의 숫자이기 때문입니다 =.

예:

arr2[1][3] = bar
arr2[1][71] = bon
arr[3][30] = sin

곧..

왜 작동하지 않는지, 가능한지 말해 줄 수 있는 사람이 있나요?

gawk 버전 GNU Awk 4.1.1, API: 1.1

감사해요.

답변1

예, 가능합니다. 그러나 스크립트의 문제는 자신이 하고 있다고 생각하는 것을 하고 있지 않다는 것입니다. 먼저 i첫 번째 레벨 배열의 인덱스로 사용합니다.

arr2[i][num] = val

즉, i1부터 배열 길이까지의 숫자가 되며, arr2[i]동일한 필드에 동일한 문자열 값이 있는 행이 있으면 해당 숫자를 덮어쓰게 됩니다.

이제 출력으로 빈 줄이 표시되는 이유(제 생각엔 그렇게 표시되는 것 같지만 실제로 그렇게 말하지는 않았습니다)는 배열에서 잘못된 순서를 사용하고 있기 때문입니다. 당신은:

arr2[i][num] = val

예를 들면 다음과 같습니다.

arr2[1][soo]=9

당신은 그 반대를 기대하는 것 같습니다.

arr2[1][9]=soo

따라서 필요한 것은 다음과 같습니다.

arr2[i][value]=num

NR충돌을 피하기 위해 기본 인덱스 로 사용되도록 배열 정의도 변경하면 다음과 같은 결과를 num얻습니다.

gawk '
{
    split($0,arr)
    for(i=1;i<=length(arr);i++){
        eq=index(arr[i],"=")
        num=substr(arr[i],eq+1)
        val=substr(arr[i],0,eq-1)
        arr2[NR][val] = num
    }
}
END{
  for(i in arr2){
    for (num in arr2[i]){
      printf "arr2[%s][%s]=%s\n", i, num, arr2[i][num]
    }
  }
}
' newfile.txt
arr2[1][3]=bar
arr2[1][9]=foo
arr2[1][30]=bin
arr2[1][71]=bon
arr2[1][84]=baz
arr2[2][3]=gar
arr2[2][9]=goo
arr2[2][30]=gin
arr2[2][71]=gon
arr2[2][84]=gaz
arr2[3][3]=sar
arr2[3][9]=soo
arr2[3][30]=sin
arr2[3][71]=son
arr2[3][84]=saz

보시다시피 arr2[2][9]이제 goo예상대로 작동합니다. 모든 것이 조금 너무 복잡합니다. 이를 다음과 같이 단순화할 수 있습니다.

$ awk -F'[ =]' '{
                    for(i=1;i<=NF;i+=2){
                        arr2[NR][$(i)]=$(i+1);
                    }
                } END{print  arr2[2][9]}' newfile.txt 
goo

관련 정보