저는 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==FNR
false인 경우, NR==FNR
true인 경우 $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
단계별로 일어나는 일은 다음과 같습니다.
filez
첫 번째 줄은 trueNR==FNR
로 평가됩니다1==1
. 따라서{a[$1]=$2;next}
실행은 스크립트의 나머지 부분을 건너뛰는 것을 의미합니다a[111]
( 특히 현재는 사용되지 않음).111
next
$3 in a && $3 = a[$3]
$3
filez
두 번째 및 마지막 줄은NR==FNR
으로 평가되고 ,2==2
다시 는 아무것도 인쇄되지 않으므로 로 설정됩니다 .{a[$1]=$2;next}
a[112]
114
$3 in a && $3 = a[$3]
next
filex
첫 번째 줄을 읽으면 , falseNR==FNR
로 평가됩니다 .3==1
{a[$1]=$2;next}
아니요다음 조건부:$3
은111
의 인덱스 값a
이므로 true$3 in a
이고 평가 됩니다$3 = a[$3]
. 결과는 빈 문자열 이 아니기 때문에 조건부 할당도 true로 평가되어 현재 행을 인쇄합니다.a[111]
111
$3
111
0
A,bb,111,xxx,nnn
filex
두 번째 및 마지막 행을 읽으면 , falseNR==FNR
로 평가됩니다 .4==2
{a[$1]=$2;next}
아니요다음 조건부: 과 는 의 인덱스 값 이므로 true 이므로 평가됩니다. 결과는 빈 문자열 이 아니기$3
때문에 조건부 할당도 true로 평가되고 현재 줄이 인쇄됩니다.112
a
$3 in a
$3 = a[$3]
a[112]
114
$3
114
0
A,cc,114,yyy,nnn
답변2
BEGIN{OFS=FS=","}
입력 및 출력 필드 구분 기호를 로 설정합니다,
.NR==FNR
첫 번째 파일에만 적용됩니다. 따라서 첫 번째 파일의 경우:a[$1]=$2
$1
index와 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
.