다음은 내 스크립트입니다(지정된 패턴이 포함된 파일을 찾기 위한).
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 awk
4.2 이상의 경우,$x
로 시작 @/
하고 끝나는 경우 /
정규식 유형의 변수로 처리됩니다.).
예를 들어 쉘 변수에 두 문자가 포함되어 있는 경우백슬래시그리고N, awk 변수에는 결국 다음이 포함됩니다.새로운 팀문자 및 gawk 4.2+의 경우 가 포함되어 있으면 @/foo/
awk 변수는 을 포함 foo
하고 유형이 됩니다 regexp
. 더 나쁜 것은 @/(xxxxx){1,20000}/
gawk가 몇 시간 동안 또는 메모리가 부족할 때까지 CPU를 점유하여 정규식을 컴파일하려고 시도하여 일종의 DoS 취약점이 된다는 것입니다.
또 다른 방법(하지만 -v
POSIX 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
-v
var=value
숫자 문자열숫자 모양인 경우(인식되는 숫자 형식의 범위는 구현에 따라 다릅니다).
위의 예에서 or이면 $2 == ENVIRON["VAR"]
문자열 비교가 되지만, or(또는 구현 및 버전에 따라)이면 숫자 비교가 되기 때문에 중요합니다. 숫자입니다. 따라서 과 는 동일한 것으로 간주됩니다.$VAR
foo
1f2
1e2
1.1
inf
0xff
awk
$2
10.0e1
100
1e2
행위:
awk 'BEGIN {var = "" ENVIRON["VAR"]}'
쉘 변수가 숫자처럼 보이 var
awk
더라도 변수는 항상 문자열로 처리되는지 확인하십시오 .$VAR
awk 'BEGIN {var = 0 + ENVIRON["VAR"]}'
이를 숫자로 변환합니다(적어도 앞부분은 숫자로 해석될 수 있음).
또는 strcoll()
일부 구현(POSIX에서 요구하는 대로)과 비교할 때, 즉 둘 중 하나 또는 둘 다 동일한 정렬 순서를 갖는 경우 a == b
하나 a
또는 둘 다 문자열이면 b
true를 반환합니다 .a
b