값이 0(숫자 0)인 경우 awk가 $1에 대해 다르게 동작하는 이유는 무엇입니까?

값이 0(숫자 0)인 경우 awk가 $1에 대해 다르게 동작하는 이유는 무엇입니까?

awk가 수신할 때"0"입력으로서 어떤 경우에는 다르게 동작합니다. 아래 코드:

var=$1
echo ""; echo -n 'o/p of $1=$1 ==>'; echo $var | awk '$1=$1'
echo "";echo -n 'o/p of {$1=$1;print} ==>';echo $var | awk '{$1=$1;print}'
echo "";echo -n 'o/p of $1==$1 ==>';echo $var | awk '$1==$1'
echo "";echo -n 'o/p of {$1==$1;print} ==>';echo $var | awk '{$1==$1;print}'

출력은"0"(숫자 0):

[root@host ~]# sh /tmp/te.sh 0

o/p of $1=$1 ==>
o/p of {$1=$1;print} ==>0

o/p of $1==$1 ==>0

o/p of {$1==$1;print} ==>0
[root@GORJALA ~]#

출력은"1"(숫자 1):

[root@host ~]# sh /tmp/te.sh 1

o/p of $1=$1 ==>1

o/p of {$1=$1;print} ==>1

o/p of $1==$1 ==>1

o/p of {$1==$1;print} ==>1
[root@host ~]#

var=0; echo $var | awk '$1=$1'및 를 사용할 때 왜 차이가 있나요 var=1; echo $var | awk '$1=$1'? 이외의 모든 숫자는 잘 작동합니다 0.

버전:

  • GNU 배시, 버전 4.2.46
  • GNU Awk 4.0.2
  • coreutils-8.22-24.el7.x86_64

답변1

로부터GNU Awk 사용자 가이드:

할당은 표현식이므로 할당된 값과 동일한 값을 갖습니다. 따라서 'z = 1'은 값이 1인 표현식입니다.

그래서

  • echo 0 | awk '$1=$1'패턴이 0(FALSE)으로 평가됩니다.

  • echo 1 | awk '$1=$1'패턴은 1(TRUE)로 평가되고 기본 작업이 print실행됩니다.

답변2

나는 그것이 숫자 값의 문제라고 생각하지 않습니다. 표준 변환이 (적어도 여기서는) 그것을 처리합니다.

OP에는 다음과 같은 네 가지 다른 awk 코드가 표시됩니다. 패턴 { action }

(a) $1 = $1

그러면 $1이 자신에게 다시 할당됩니다. 부울 테스트가 아니며 (효과적으로) 아무런 작업도 수행하지 않으며 $1의 값을 반환합니다. $1이 0이면 패턴은 다음과 같습니다.거짓그리고 기본값인쇄 작업을 완전히 건너뜁니다.. $1이 0이 아닌 경우입력이 인쇄됩니다.

(b) { $1 = $1; 인쇄; }

이는 $1를 자신에게 재할당하며, 또한 작동하지 않습니다. 패턴이 없으면 작업이 수행되고 입력이 수행됩니다.항상 인쇄됨.

(c) $1 == $1

이는 부울 표현식입니다.항상 사실. 0은 0이고 1은 1입니다(그리고 aardvark는 aardvark입니다). 조치가 없으면 입력은 다음과 같습니다.항상 인쇄됨.

(d) { $1 == $1; 인쇄; }

패턴이 없습니다. 비교는 폐기되는 실제 부울로 평가됩니다. 입력은항상 인쇄됨.

답변3

기존 답변은 이유를 설명하지 못합니다.

echo 0 | awk '$0="0"'
echo 0 | awk '$0=substr($0,1)'
echo 0 | awk '$0=$0""'

모두 인쇄 0되지만

echo 0 | awk '$0'
echo 000 | awk '$0'

아무 것도 인쇄하지 않지만 모든 경우에 패턴 표현식은 0.

0한 경우에는 참이고 다른 경우에는 거짓입니까?

그 이유는 "필드 변수"(연산자의 결과 $)가 다음과 같이 처리되기 때문입니다.특별한 경우및 (가능한 경우)은 자동으로 다음으로 변환됩니다.숫자 문자열, 수치적으로 와 동일하면 0부울 컨텍스트에서 사용될 때 false로 간주됩니다.

문자열 값은숫자 문자열다음 중 하나에서 발생한 경우:

  1. 필드 변수

  2. getline()함수 에서 입력

  3. FILENAME

  4. ARGV배열 요소

  5. ENVIRON배열 요소

  6. split()함수 에 의해 생성된 배열 요소

  7. 명령줄 변수 할당

  8. 다른 숫자 문자열 변수에서 변수 할당

그리고 [숫자처럼 보이면 전체 설명을 읽어보세요.여기]

다음 내용도 읽어보세요.RATIONALE숫자 문자열의 개념과 이 특수 케이스가 필요한 이유, 특히 echo 0 000 | awk '$1==$2'true와 같지만 그렇지 않은 비교에 대한 부분입니다 echo 0 | awk '$1=="000"'.


또 다른 특이한 점은 적어도 일부 구현에서는 $0하위 필드에 대한 할당으로 인해 재계산이 발생하면 (현재 입력 레코드) 마법의 "숫자 문자열" 속성이 손실된다는 점입니다.

$ echo 0 | gawk '{$1=0} $0'
0

이는 표준 awk의 기반이 되는 nawk/bwk의 동작과 일치하지만(mawk의 동작은 아님) 표준에서 다루지 않는 것 같습니다.

또한 awk 구현은 입력에서 와 해당 부동 소수점 숫자를 인식할 수 있지만 이에 대한 지원은 불확실하고 일관성 NANINF없습니다 . INFINITY예를 들어 여전히 물릴 수 있습니다.

echo But his daughter named Nan | awk '$NF'

FreeBSD의 awk(bwk, original-awk)에서는 아무것도 인쇄하지 않습니다.

답변4

왜냐하면 $0은전체 기록(완전한 줄), $1, $2, 는필드(보통 공백으로 구분됨)입니다.

관련 정보