awk의 인쇄 배열 결과를 이해할 수 없습니까?

awk의 인쇄 배열 결과를 이해할 수 없습니까?

간단한 file포함의 경우:

1        a
2        b
3        c
4        d
5        e
6        f
7        g
8        h
9        i
10       j

나는 다음 명령을 사용합니다.

awk 'lines[NR]=$0 { print $lines[2]}' 

그것은 나에게 다음을 제공합니다:

1        a
b
c
d
e
f
g
h
i
j

어떻게 그리고 왜? 이렇지 않아야합니까?

2 b

또한 다음을 업데이트하면

awk '{lines[NR]=$0} END { print lines[2]}' awk.write

2 b

그리고 사용$

j

답변1

awk변수와 작업 흐름을 혼동하고 있습니다 . 아마도 원하는 것은 다음과 같습니다(두 번째 줄만 인쇄).

awk '{lines[NR]=$0} END{print lines[2]}' file

그러나 이는 다음과 같이 보다 간단하게 수행할 수 있습니다.

awk 'NR==2' file

질문에 다음을 수행하도록 명령합니다.

awk 'lines[NR]=$0 { print $lines[2]}' 
  • lines[NR]=$0awk여기서는 조건으로 해석됩니다 . awk다음과 같은 메커니즘을 갖춘 워크플로가 있습니다(모든 행에 적용됨 ) 'condition{instructions}'. lines[NR]=$0배열을 채우지만 이는 항상 true인 조건입니다. 이것이 바로 {...}명령 블록이 각 행에 대해 실행되는 이유입니다.
  • print $lines[2]배열의 두 번째 항목은 인쇄되지 않습니다 lines[2]. $lines[2]이름이 배열의 두 번째 항목 내용인 변수로 확장됩니다. 첫 번째 줄은 초기화되지 않았으므로 print인수 없이 호출됩니다. 이는 전체 행을 인쇄한다는 의미입니다. 그러나 (다른 모든 줄에서) 설정하면 로 확장됩니다 print $2. 즉, 줄의 두 번째 필드가 인쇄됩니다.

답변2

에서는 awk참조를 통해 변수 값에 액세스할 수 있습니다.

$ awk 'BEGIN {var=1; print var}'
1

가지다특수 변수필드 변수라고 하는 는 $기호 뒤에 숫자나 표현식이 오는 방식으로 표시됩니다. 따라서 둘 다 첫 번째 필드의 값을 $1제공합니다 .$(0+1)

lines귀하의 예에서는 키가 행 번호이고 값이 전체 행인 연관 배열을 만들었습니다 . for 를 2사용해야 하는 키 값을 얻으려면 n번째 필드를 참조해야 합니다 lines[2]. $lines[2]여기서 n번째는 의 반환 값입니다 lines[2].

첫 번째 행을 처리할 때 lines[2]초기화되지 않아 반환될 수 있습니다.0또는비어 있는또는 다른 것(POSIX는 이 동작을 지정하지 않습니다). 어쨌든, print과 는 print $0동일합니다. 그래서 가 있는 이유는 첫 번째 행 1 a입니다 .$0

두 번째 행부터 시작하여 lines[2]두 번째 행의 내용으로 할당됩니다. 즉 2 b, 숫자 컨텍스트에서 2 b다음을 반환합니다 .2, 두 번째 행에서 두 번째 필드의 값을 가져오는 $2식입니다.


이제 이후의 표현식은 $POSIX에 지정된 숫자 결과를 반환한다고 보장되지 않으므로 다음과 같습니다.

필드 변수는 "$" 뒤에 숫자나 숫자 표현식이 와야 합니다. 이 맥락에서 음이 아닌 정수 이외의 것으로 평가되는 지정되지 않은 필드 숫자 표현식의 효과는 초기화되지 않은 변수 또는 문자열 값을 숫자 값으로 변환할 필요가 없습니다.

따라서 구현이 중단되는 상황이 있을 수 있습니다. 적어도Brian Kernighan 자신의 버전:

$ echo 1 2 | bawk '{print $b}'
bawk: illegal field $(), name "b"
 input record number 1, file 
 source line number 1

0어떤 경우든 다음을 추가하여 숫자 컨텍스트에서 표현식을 강제로 평가할 수 있습니다.

$ echo 1 2 | awk '{print $(b+0)}'
1 2

관련 정보