외부 셸 변수를 awk
스크립트에 전달하는 몇 가지 방법을 찾았지만 및
에 대해 혼란스러워합니다.
먼저 셸 스크립트로 시도해 보았습니다:
$ v=123test
$ echo $v
123test
$ echo "$v"
123test
그런 다음 어색하게 시도했습니다:
$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123
왜 차이가 있을까요?
마지막으로 이것을 시도해 보았습니다:
$ awk 'BEGIN{print " '$v' "}'
$ 123test
$ awk 'BEGIN{print ' "$v" '}'
awk: cmd. line:1: BEGIN{print
awk: cmd. line:1: ^ unexpected newline or end of string
혼란스럽습니다.
셸 변수를
awk
로 가져오기로 가져오는 방법은 여러 가지가 있습니다. 어떤 방법은 다른 방법보다 낫습니다. 여기서는 대부분의 방법을 다룹니다. 의견이 있으시면 아래에 남겨 주세요.
v옵션 사용: (참고로
-v뒤에 공백을 사용하지 않으면 이식성이 떨어집니다. 예:
awk -v var=가 아닌
awk -vvar=`)
variable="line one\nline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two
이것은 대부분의 awk
와 호환되어야 하며, BEGIN
블록에서도 변수를 사용할 수 있습니다:
변수가 여러 개 있는 경우:
awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'
경고. 에드 모튼이 쓴 것처럼, 이스케이프 시퀀스는 \t
가 \t
가 아닌 실제 탭
이 되도록 해석됩니다. ENVIRON[]을 사용하여 해결하거나
ARGV[]`를 통해 액세스할 수 있습니다.
PS 세 개의 세로 막대를 구분 기호 |||
로 사용할 경우 이스케이프할 수 없으므로 `-F"[|][|][|][|]"를 사용하세요.
프로그램/함수에서 awk
로 데이터를 가져오는 예제(여기서는 날짜가 사용됨)
awk -v time="$(date +"%F %H:%M" -d '-1 minute')" 'BEGIN {print time}'
여기서는 awk
코드 뒤에 변수를 가져옵니다. 이 방법은 BEGIN
블록에 변수가 필요하지 않은 한 잘 작동합니다:
variable="line one\nline two"
echo "input data" | awk '{print var}' var="${variable}"
or
awk '{print var}' var="${variable}" file
이 방법은 여러 변수가 있는 경우에도 작동합니다.
awk '{print a,b,$0}' a="$var1" b="$var2" file
이런 식으로 변수를 사용하면 BEGIN
블록에서 작동하지 않습니다:
echo "input data" | awk 'BEGIN {print var}' var="${variable}"
변수를 지원하는 셸(Bash 포함)에서 here-string을 사용하여 awk
에 변수를 추가할 수도 있습니다:
awk '{print $0}' <<< "$variable"
test
와 동일합니다:
printf '%s' "$variable" | awk '{print $0}'
추신: 변수를 파일 입력으로 취급합니다.
ENVIRON
입력TrueY가 작성한 것처럼 ENVIRON
을 사용하여 환경 변수를 인쇄할 수 있습니다.
AWK를 실행하기 전에 변수를 설정하면 다음과 같이 출력할 수 있습니다:
X=MyVar
awk 'BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}'
MyVar /bin/bash
ARGV
입력스티븐 페니가 쓴 것처럼 ARGV
를 사용하여 데이터를 어색하게 만들 수 있습니다:
v="my data"
awk 'BEGIN {print ARGV[1]}' "$v"
my data
BEGIN이 아닌 코드 자체에 데이터를 가져올 수 있습니다:
v="my data"
echo "test" | awk 'BEGIN{var=ARGV[1];ARGV[1]=""} {print var, $0}' "$v"
my data test
코드 내 ##변수: 주의해서 사용하세요
awk코드 내에서 변수를 사용할 수 있지만 지저분하고 읽기 어렵고,
Charles Duffy가 지적했듯이 이 버전은 코드 인젝션의 희생양이 될 수도 있습니다. 누군가 변수에 나쁜 내용을 추가하면
awk` 코드의 일부로 실행됩니다.
이것은 코드 내에서 변수를 추출하여 작동하므로 변수가 코드의 일부가 됩니다.
변수를 사용하여 동적으로 변경되는 awk
를 만들고 싶다면 이런 식으로 할 수 있지만 일반 변수에는 사용하지 마세요.
variable="line one\nline two"
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
다음은 코드 삽입의 예입니다:
variable='line one\nline two" ; for (i=1;i<=1000;++i) print i"'
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
1
2
3
.
.
1000
이런 식으로 awk
에 많은 명령을 추가할 수 있습니다. 유효하지 않은 명령으로 충돌을 일으킬 수도 있습니다.
변수 $변수
는 항상 큰따옴표로 묶는 것이 좋습니다.
그렇지 않으면 여러 줄이 긴 한 줄로 추가됩니다.
예시:
var="Line one
This is line two"
echo $var
Line one This is line two
echo "$var"
Line one
This is line two
큰따옴표 없이도 발생할 수 있는 기타 오류입니다:
variable="line one\nline two"
awk -v var=$variable 'BEGIN {print var}'
awk: cmd. line:1: one\nline
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: one\nline
awk: cmd. line:1: ^ syntax error
작은따옴표를 사용하면 변수 값이 확장되지 않습니다:
awk -v var='$variable' 'BEGIN {print var}'
$variable
이 자주 묻는 질문을 참조하세요.
셸 변수에서 백슬래시를 처리하는 방법에 따라 이 중 하나를 사용합니다(avar
는 어색한 변수, svar
는 셸 변수):
awk -v avar="$svar" '... avar ...' file
awk 'BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...' "$svar" file
자세한 내용 및 기타 옵션은 http://cfajohnson.com/shell/cus-faq-2.html#Q24 을 참조하세요. 위의 첫 번째 방법은 거의 항상 최선의 선택이며 가장 명확한 의미를 갖습니다.
명령줄 옵션]1 -v
에 변수 이름(v
)과 환경 변수 값(=
)을 함께 전달할 수 있습니다("${v}"
):
% awk -vv="${v}" 'BEGIN { print v }'
123test
또는 v
를 훨씬 적게 사용하여 더 명확하게 만들 수도 있습니다:
% environment_variable=123test
% awk -vawk_variable="${environment_variable}" 'BEGIN { print awk_variable }'
123test