awk 배열 해석?

awk 배열 해석?

저는 awk 프로그래밍을 처음 접했고 배열 작동 방식을 배우고 있습니다. 이 코드를 찾았습니다.

awk 'BEGIN{OFS=FS=","}NR==FNR{a[$1]=$2;next}$3 in a && $3 = a[$3]' filez filex

그들은 $1그것을 배열에 대한 인덱스로 넣고 인덱스와 같으면 $2값으로 넣습니다 . 첫 번째 파일에는 2개의 열만 있으므로 이것이 무엇을 의미하는지 이해가 되지 않습니다. 두 번째 파일과 비교하여 어디서 나온 것입니까 ? ! ?$3$3 = a[$3]$3$3

입력 파일 filez:

111,111
112,114
113,113

입력 파일 filex:

A,bb,111,xxx,nnn
A,cc,112,yyy,nnn
A,dd,113,zzz,ppp

답변1

이 스크립트의 목적은 두 번째 파일( )의 세 번째 열에 있는 값을 filex첫 번째 파일( )의 두 번째 열에 저장된 해당 값으로 바꾸는 것입니다 filez.

NR처리된 첫 번째 파일의 첫 번째 줄을 기준으로 현재 줄의 줄 번호입니다. "글로벌" 라인 카운터입니다. FNR현재 처리 중인 파일의 시작 부분을 기준으로 하는 현재 줄 번호입니다.
NR==FNR첫 번째 파일에 대해서만 true로 평가되는 조건입니다. 해당 연산( {a[$1]=$2;next})은 첫 번째 파일 전체를 한 줄씩 사전에 넣습니다. 사전은 a첫 번째 열의 해당 값을 기반으로 첫 번째 파일의 두 번째 열 값을 찾는 것이 목적인 연관 배열입니다. 나머지 조건을 next건너 awk뛰고 루프를 다시 시작하여 다음 줄을 읽습니다.

$3 in a && $3 = a[$3]잠재적인 부작용이 있는 조건(할당됨)입니다 $3. 두 번째 파일만 평가됩니다( NR==FNRfalse인 경우, NR==FNRtrue인 경우 $3 in a && $3 = a[$3]건너뜁니다 ). 각 행에 대해 세 번째 필드(색인)의 값이 Dictionary 에서 발견되면 a이를 사전의 해당 값으로 바꿉니다. 그러다가 $3 = a[$3]평가 결과가 참이면 해당 라인이 출력된다(AWK 프로그램에서는 기본적으로 조건(또는 "패턴")-액션 쌍으로 구성되기 때문에 조건이나 액션 중 하나를 생략할 수 있고 생략된 액션은 동일하다 print) .

이것이 단축되었다고 가정하십시오 filez:

111,111
112,114

그리고 filex:

A,bb,111,xxx,nnn
A,cc,112,yyy,nnn

단계별로 일어나는 일은 다음과 같습니다.

  1. filez첫 번째 줄은 true NR==FNR로 평가됩니다 1==1. 따라서 {a[$1]=$2;next}실행은 스크립트의 나머지 부분을 건너뛰는 것을 의미합니다 a[111]( 특히 현재는 사용되지 않음).111next$3 in a && $3 = a[$3]$3

  2. filez두 번째 및 마지막 줄은 NR==FNR으로 평가되고 , 2==2다시 는 아무것도 인쇄되지 않으므로 로 설정됩니다 .{a[$1]=$2;next}a[112]114$3 in a && $3 = a[$3]next

  3. filex첫 번째 줄을 읽으면 , false NR==FNR로 평가됩니다 .3==1{a[$1]=$2;next}아니요다음 조건부: $3111의 인덱스 값 a이므로 true $3 in a이고 평가 됩니다 $3 = a[$3]. 결과는 빈 문자열 이 아니기 때문에 조건부 할당도 true로 평가되어 현재 행을 인쇄합니다.a[111]111$31110

    A,bb,111,xxx,nnn
    
  4. filex두 번째 및 마지막 행을 읽으면 , false NR==FNR로 평가됩니다 .4==2{a[$1]=$2;next}아니요다음 조건부: 과 는 의 인덱스 값 이므로 true 이므로 평가됩니다. 결과는 빈 문자열 이 아니기 $3때문에 조건부 할당도 true로 평가되고 현재 줄이 인쇄됩니다.112a$3 in a$3 = a[$3]a[112]114$31140

    A,cc,114,yyy,nnn
    

답변2

  • BEGIN{OFS=FS=","}입력 및 출력 필드 구분 기호를 로 설정합니다 ,.
  • NR==FNR첫 번째 파일에만 적용됩니다. 따라서 첫 번째 파일의 경우:
    • a[$1]=$2$1index와 value로 $2배열에 넣습니다 a.
    • next이 스크립트 줄의 나머지 부분을 건너뜁니다.

다시 말해 보세요 next.나머지 스크립트는 두 번째 파일에 대해서만 실행됩니다.(그리고 세 번째, 네 번째... 파일이 존재한다면).

  • $3 in a && $3 = a[$3]세 번째 필드가 배열의 키인 경우 a세 번째 필드를 로 바꿉니다 a[$3]. 이제 이는 작동 환경(즉, 내부가 아님)에 있지 않으므로 {}두 조건이 모두 true인 경우 현재 레코드가 인쇄되어야 함을 의미합니다. 그렇지 않으면 아무것도 할 수 없습니다.

일반적으로 말하면, 오른쪽의 조건은 할당이므로 왼쪽이 참이면 결과는 참입니다. 그러나 빈 문자열이나 숫자 0이 할당되면 할당은 false로 평가됩니다. 이는 의도적일 수 있지만 종종 프로그래머가 알아차리지 못하는 극단적인 경우입니다. 그것을 보려면 awk 코드를 사용해보십시오

filez:

111,111
112,114
113,113
000,000

filex:

A,bb,111,xxx,nnn
A,cc,112,yyy,nnn
A,dd,113,zzz,ppp
A,ee,000,uuu,aaa

마지막 줄의 경우 $3 in a할당 $3 = a[$3] 이 0이므로 해당 줄이 인쇄되지 않습니다.

$ awk 'BEGIN{OFS=FS=","}NR==FNR{a[$1]=$2;next}$3 in a && $3 = a[$3]' filez filex
A,bb,111,xxx,nnn
A,cc,114,yyy,nnn
A,dd,113,zzz,ppp

OP가 요청한 설명:

기억하세요: 배열은 다음으로 채워집니다.a[$1]=$2 첫 번째 파일에서, filez.이(가)
$3 = a[$3]실행되었습니다.두 번째 파일의 경우, filex.
예: 두 번째 줄에서는 filez- a[$1]=$2> a[112] = 114. 두 번째 줄에는 filex- $3 = a[$3]> 입니다 112=a[112]=114.

관련 정보