awk에서 쉘 변수 사용

awk에서 쉘 변수 사용

다음은 내 스크립트입니다(지정된 패턴이 포함된 파일을 찾기 위한).

find . -type f \
    -exec awk -v vawk="$1" '/'"$vawk"'/ {c++} c>0 { print ARGV[1]; exit 0 } END { if (! c) {exit 1}}' \{\} \;

매개변수가 있는 스크립트를 사용하고 싶습니다§:

MyScript.sh pattern

내 문제는 $1변수를 awk.

내 스크립트를 디버깅하려고 할 때

bash -x MyScript.sh pattern

출력은 다음과 같습니다.

+ find . -type f -exec awk -v vawk=pattern '// {c++} c>0 {print ARGV[1] ; exit 0 } END { if (! c) {exit 1}}' '{}' ';'

변수 $vawk가 비어 있는 것 같습니다.

어떤 아이디어가 있나요?

답변1

awk 변수와 쉘 변수를 혼동하신 것 같습니다. awk -v vawk="$1"만들다변수 이름이 지정되었지만 vawk사용하려고 합니다.껍데기구문 ( $vawk). 쉘에 라는 변수가 없기 때문에 작동하지 않습니다 vawk. 내 생각엔 당신이 원하는 건

awk -v vawk="$1" '$0 ~ vawk { c++ } # ...'
#                      ^ awk variable syntax

답변2

앞으로지금은 다음과 같이 폐쇄되었습니다.복사질문이는 awk의 변수 전달 제한에 대한 경고를 포함하므로 유용할 수 있습니다.

쉘 변수는 다음과 같습니다:껍데기바꾸다. 그것을변수에는 다음과 같은 구문이 필요합니다.

awk -v x="$x" '$2 == x {print $1}' infile

또는

awk '$2 == x {print $1}' x="$x" infile

그러나 문제가 발생합니다. 이스케이프 시퀀스가 ​​확장됩니다.

또한 GNU awk4.2 이상의 경우,$x로 시작 @/하고 끝나는 경우 /정규식 유형의 변수로 처리됩니다.).

예를 들어 쉘 변수에 두 문자가 포함되어 있는 경우백슬래시그리고N, awk 변수에는 결국 다음이 포함됩니다.새로운 팀문자 및 gawk 4.2+의 경우 가 포함되어 있으면 @/foo/awk 변수는 을 포함 foo하고 유형이 됩니다 regexp. 더 나쁜 것은 @/(xxxxx){1,20000}/gawk가 몇 시간 동안 또는 메모리가 부족할 때까지 CPU를 점유하여 정규식을 컴파일하려고 시도하여 일종의 DoS 취약점이 된다는 것입니다.

또 다른 방법(하지만 -vPOSIX awk 또는 nawk가 필요함(Solaris에서 여전히 사용되는 1970년대 awk와 반대 /bin/awk))은 환경 변수를 사용하는 것입니다.

x="$x" awk '$2 == ENVIRON["x"] {print $1}' infile

또 다른 방법(여전히 최신 awk 사용)은 awk에서 ARGV 배열을 사용하는 것입니다.

awk -- 'BEGIN {x = ARGV[1]; delete ARGV[1]}
  $2 == x {print $1}' "$x" infile

또한 // ARGV또는 인수를 사용하든 해당 문자열은 다음과 같이 처리됩니다.ENVIRON-vvar=value숫자 문자열숫자 모양인 경우(인식되는 숫자 형식의 범위는 구현에 따라 다릅니다).

위의 예에서 or이면 $2 == ENVIRON["VAR"]문자열 비교가 되지만, or(또는 구현 및 버전에 따라)이면 숫자 비교가 되기 때문에 중요합니다. 숫자입니다. 따라서 과 는 동일한 것으로 간주됩니다.$VARfoo1f21e21.1inf0xffawk$210.0e11001e2

행위:

awk 'BEGIN {var = "" ENVIRON["VAR"]}'

쉘 변수가 숫자처럼 보이 var awk더라도 변수는 항상 문자열로 처리되는지 확인하십시오 .$VAR

awk 'BEGIN {var = 0 + ENVIRON["VAR"]}'

이를 숫자로 변환합니다(적어도 앞부분은 숫자로 해석될 수 있음).


또는 strcoll()일부 구현(POSIX에서 요구하는 대로)과 비교할 때, 즉 둘 중 하나 또는 둘 다 동일한 정렬 순서를 갖는 경우 a == b하나 a또는 둘 다 문자열이면 btrue를 반환합니다 .ab

관련 정보