0.축하해요. gawk에서 버그를 발견한 것 같습니다.

0.축하해요. gawk에서 버그를 발견한 것 같습니다.

FPAT 정규 표현식과 함께 NF를 사용하면 쉼표가 필드로 처리됩니다. 나는 NF와 FPAT를 사용하는 것을 선호합니다.

1) NF - 레코드의 실제 필드 수로 출력을 제한합니다.

2) FPAT – 3행과 같이 인용된 필드에 포함된 쉼표를 처리합니다.

 "Bus Driver, City/Transit",51

3) 열 수가 다른 레코드 6이 있는 여러 입력 파일에 대한 awk 스크립트 - 레코드 6은 파일 내용의 열 이름/제목입니다.

테스트의 출력인 첫 번째 test1은 고정 값을 필드 수로 사용하고 두 번째 test2는 NF를 필드 수로 사용합니다.

gawk 4.1.4 사용

    BEGIN {
            FPAT = "(^,)|([^,]+)|(\"[^\"]+\")"
            OFS = "\t"
        }

    NR == 6 {

       for (i = 1; 6 >= i; ++i) {
       #for (i = 1; NF >= i; ++i) {

           colName[i] = $i
           print "Column Name: " colName[i]

    }    

      { print "", "number of fields: " NF }
    }

입력 파일은 레코드 6에서 시작합니다: NR == 6 {...

    Occupation,States Licensed 
    Barber,51 
    "Bus Driver, City/Transit",51

내 예상/원하는 결과:

    Column Name: Occupation
    Column Name: States Licensed
        number of fields: 2

테스트 1: for (i = 1; 6 >= i; ++i) {...

출력은 정확합니다. 물론, 유효하지 않지만 고정 값 6을 사용하여 표시되는 4개의 열/필드를 제외하고는 제가 예상/원했던 것입니다.

    Column Name: Occupation
    Column Name: States Licensed
    Column Name: 
    Column Name: 
    Column Name: 
    Column Name: 
        number of fields: 2

테스트 2: for (i = 1; NF >= i; ++i) {...

출력은 내가 기대하거나 원했던 것과 다릅니다. 쉼표는 필드를 나타냅니다.

    Column Name: Occupation
    Column Name: ,
    Column Name: States Licensed
        number of fields: 3

답변1

0.축하해요. gawk에서 버그를 발견한 것 같습니다.

나는 이것을 아주 작은 예로 축소했습니다. (더 간단한 문자열로 결함을 설명할 수도 있지만 FPAT10분을 더 소비하고 싶지 않았습니다.) 기본적으로 이와 같은 입력에 대해 foo,bar두 가지 다른 결과를 얻을 수 있습니다.

첫 번째 사례:

NF = 2
$1 = foo
$2 = bar
$3 =

그리고

사례 B:

NF = 3
$1 = foo
$2 = ,
$3 = bar

이 코드는사례 B:

BEGIN {
        FPAT = "^,|[^,]+"
}

{
        print "NF =", NF
        print "$1 =", $1; print "$2 =", $2; print "$3 =", $3
}

(괄호는 필요하지 않기 때문에 제거했습니다 FPAT. 쉼표가 포함될 수 있는 인용 문자열을 처리하는 정규식 부분을 제거하고 코드를 최소한으로 줄였습니다.)

사용

에코 foo, 바 |awk_script 위의 이름

그러나 - 적어도 gawk 버전 4.1.1에서는 - $1액세스하기 전에 액세스 하면 NF다음을 얻습니다.사례 A.  진술 순서를 바꾸 print거나 다음과 같은 말도 안되는 조합을 통해 이를 증명할 수 있습니다.

{
        temp = $1                       # We will never use this.
        print "NF =", NF
        print "$1 =", $1; print "$2 =", $2; print "$3 =", $3
}

이것은 분명히 불가능한 실수입니다.입장필드는 다른 것의 값을 변경해야 합니다. 

1. 그래서 우리에게는 해결책이 있습니다.

temp = $1루프 앞에 추가하면 for(를 사용하여) 원하는 결과를 얻을 수 있기를 바랍니다  NF.

2. 진짜(?) 답은:

위에서는 A사례나 B사례를 '옳다', '그르다'라고 부르는 것을 일부러 피했습니다. 상황 A는 당신이 원하는 상황이지만, 상황 B는 실제로 당신이 원하는 상황일 수도 있습니다.옳은FPAT결과는 사용 중인 값입니다. 이것은 당신이 필드를 원한다고 말하는 것 같습니다

  • 쉼표로 시작하는 문자열, 또는
  • 쉼표가 아닌 하나 이상의 문자로 구성된 문자열, 또는
  • 따옴표, 하나 이상의 따옴표가 아닌 문자로 구성된 문자열 및 다른 따옴표입니다.

그러나 쉼표가 필드가 되는 것을 원하지는 않습니다. 두 번째와 세 번째 옵션만 필요합니다. 그 설정을 찾았어요

FPAT = "[^,]+|\"[^\"]+\""

올바른 결과를 줄 것입니다.

관련 정보