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에서 버그를 발견한 것 같습니다.
나는 이것을 아주 작은 예로 축소했습니다. (더 간단한 문자열로 결함을 설명할 수도 있지만 FPAT
10분을 더 소비하고 싶지 않았습니다.) 기본적으로 이와 같은 입력에 대해 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 = "[^,]+|\"[^\"]+\""
올바른 결과를 줄 것입니다.