awk에서 if 조건을 구현하고 싶습니다. 아래와 같이 "simple_if"라는 파일 이름을 만들었습니다.
BEGIN{
num=$1;
if (num%2==0)
printf "%d is Even number.\n",num;
else printf "%d is odd Number.\n",num
}
그런 다음 아래와 같이 $1의 매개변수로 10을 전달하여 프로그램을 실행합니다.
awk -f simple_if 10
그러나 입력을 허용하지 않고 대신 0을 표시합니다. 산출:
0 is Even number.
awk에서 사용자로부터 가치를 얻는 방법은 무엇입니까?
답변1
명령줄 끝에 제공된 인수는 일반적으로 스크립트가 읽을 파일 이름 awk
으로 처리됩니다 . awk
명령줄에서 변수를 설정하려면 -v variable=value
를 사용하세요.
awk -v num=10 -f script.awk
이렇게 하면 num
스크립트에서 변수로 사용할 수 있습니다. 위의 예에서 변수의 초기값은 10입니다.
ENVIRON["variable"]
스크립트에서 읽기 환경 변수를 사용 하거나 ( 이름이 지정된 일부 환경 변수의 경우 variable
) 명령줄 인수를 볼 수도 있습니다 . 여기서 는 양의 정수입니다 ARGV[n]
.n
$1
in 을 사용하면 awk
현재 레코드의 첫 번째 필드 값을 참조하지만 블록 내에서 사용하기 때문에 BEGIN
아직 어떤 파일에서도 데이터를 읽지 않았습니다.
코드의 숫자는 산술 컨텍스트에서 사용되는 빈 변수이므로 0으로 해석됩니다.
답변2
$1
첫 번째 명령줄 인수가 아니라 줄이 분할된 후의 첫 번째 필드입니다 ( 아직 줄이 분할되지 않았으므로 FS
빈 문자열이 됩니다 ).BEGIN
명령줄 매개변수는 배열에 있습니다 ARGV
.
$ awk 'BEGIN { for(i = 1; i < ARGC; i++) print ARGV[i] }' 1st 2nd 3rd
1st
2nd
3rd
ARGV[0]
항상 통역사의 이름( awk
또는 gawk
등)입니다.
awk
명령줄 인수를 무시하고 나중에 파일로 열지 않으려면 이를 제거하거나 빈 문자열로 설정해야 합니다. 예 : ARGV[1]=""
.
참고로, 이 형식의 모든 인수는 var=value
의 변수 할당으로 해석되어 awk
평가됩니다.뒤쪽에이미 처리되기 전의 파일 매개변수:
$ echo yes > file
$ awk '{ gsub(/e/, var); print }' var=1 file var=2 file var=3 file
y1s
y2s
y3s
양식의 실제 파일 이름을 사용하려면 key=val
상대 awk
또는 절대 경로로 전달해야 합니다. awk '{...}' ./key=val
.
답변3
user313992가 언급한 핵심 사항을 지적하고 싶습니다.답변.
awk가 명령줄 인수를 무시하고 나중에 파일로 열지 않으려면 이를 제거하거나 빈 문자열로 설정해야 합니다. ARGV[1]="".
POSIX awk에 따르면문서, 인수는 다음과 같습니다.오직두 가지 형식 중 하나로 해석됩니다.
- 읽을 파일
- 과제 형식:
var=val
따라서 지정된 매개변수가 기존 파일이 아니고 할당 형태가 아닌 경우,오직이 매개변수를 읽은 후에는 awk가 실패합니다.
BEGIN {
# this is OK:
for (i=1; i<ARGC; i++) {
print "+++ ", ARGV[i]
}
# action blocks will fail, because file reading has started
{
print $1
}
따라서 존재하지 않는 매개변수를 파일로 지정하는 것도 가능하지만, ARGV
해당 블록에 작업을 수행하기 전에 해당 매개변수를 삭제해야 한다는 점을 기억해야 합니다.
예 -
#!/bin/awk -f
#
# Bin count using thresholds given at argv. E.g.
#
# ./bin_count 0.1 0.01 0.001 0.0001 <./data | sort
# < 0.000100: 3
# < 0.001000: 12
# < 0.010000: 56
# < 0.100000: 100
BEGIN {
for (i=1; i<ARGC; i++) counts[ARGV[i]] = 0
delete ARGV # <<<<< important
}
{
$1 = $1 < 0 ? -$1 : $1
for (bin in counts) {
if ($1 < bin) { counts[bin]++; }
}
}
END {
for (bin in counts) {
printf("< %f: %d\n", bin, counts[bin])
}
}
답변4
다른 C 유사 프로그램과 마찬가지로 일반 Awk는 GNU gawk
특정 동작, 파이프, 리디렉션( <
) 또는 -v
(변수 할당) 옵션을 사용하지 않고도 명령줄 인수를 처리하는 데 문제가 없습니다.
입력 매개변수 처리 ARGC
(매개변수계산, 정수) 및 ARGV
(매개변수벡터, "목록"의 또 다른 단어)이 모두 포함되어 있습니다.수동.
Mosvy는 배경을 설명하고 구문 분석을 요약하는 작업을 훌륭하게 수행합니다 ARGV
. 이는 독립형 쉘 스크립트로 구현되고 macOS 및 GNU/Linux에서 테스트된 원래 목표입니다.
simple_if.awk
#!/usr/bin/awk -f
##
## simple_if - tell user if a number given as an argument is even or odd
##
## Example: ./simple_if.awk 11
##
BEGIN {
num = ARGV[1];
# if you expect to arguments AND read from one or more input files, you need
# to remove the arguments from ARGV so Awk doesn't attempt to open them as
# files (causing an error)
#ARGV[1] = "";
if (num % 2 == 0) {
printf "%d is an even number.\n", num;
} else {
printf "%d is an odd number.\n", num;
}
}
이와 같은 awk 스크립트를 만드십시오.실행 가능 파일를 사용하려면 chmod a+x scriptname.awk
에 드롭하면 $PATH
다른 Bash, Python, Perl 스크립트, C 프로그램 등과 마찬가지로 실행됩니다.
awk
시스템의 다른 곳에 존재하는 경우 #!
해당 행을 적절하게 업데이트하십시오 /usr/bin/env
.awk
~ 해야 하다-f
스크립트를 실행하는 옵션이 있으며 ...복잡해.
이름 .awk
은 필수가 아닙니다.별말씀을요, 그러나 편집자가 적절한 구문 강조를 활성화하는 데 도움이 될 수 있습니다. 이 기능을 끄면 아무도 그것이 Awk 스크립트인지 알 필요가 없습니다.
다음은 유용한 작업을 수행하고 합리적인 오류 처리 기능을 갖춘 보다 완전한 예입니다.
simple_stats.awk
#!/usr/bin/awk -f
##
## simple_stats - do simple 1-variable statistics (min/max/sum/average) on
## the first column of its input file(s)
##
## examples: ./simple_stats min numbers.txt
## ./simple_stats all numbers.txt # all stats
## ./simple_stats sum <(du MyFiles) # Bash proc. substitution
##
## # specify '-' as the filename when reading from stdin
## seq 1 100 | ./simple_stats avg -
##
BEGIN {
# expect stats operation as the first argument
op = ARGV[1]
# unset this array index so Awk doesn't try opening it as a file later
# ref: https://www.gnu.org/software/gawk/manual/html_node/ARGC-and-ARGV.html
ARGV[1] = ""
# if you wanted to process multiple command line arguments here, you could
# loop over ARGV, using something like
# for (i=0; i<ARGC; i++) { if (ARGV[i] == "...") { ... } }
if (op !~ /^(min|max|sum|avg|all)$/) {
print "ERROR: Expected one of min/max/sum/avg/all." >"/dev/stderr"
# 'exit' in BEGIN will always run the EXIT block, if one exists
# see https://www.gnu.org/software/gawk/manual/html_node/Assert-Function.html
_assert_exit = 1
exit 1
}
# ordinarily Awk reads stdin without specifying; here, '-' seems necessary
if (ARGV[2] == "") {
print "ERROR: Need an input file (or '-' for stdin)." >"/dev/stderr"
_assert_exit = 1
exit 1
}
}
# 'min' needs an initial value so take the first record
NR == 1 { min = $1 }
# for every input line (including the first)...
{
sum += $1
if ($1 > max) max = $1
if ($1 < min) min = $1
}
END {
if (_assert_exit) exit 1; # if 'exit' was pending from BEGIN block
if (op == "min" || op == "all")
printf "The minimum is: %15d\n", min
if (op == "max" || op == "all")
printf "The maximum is: %15d\n", max
if (op == "sum" || op == "all")
printf "The sum is: %15d\n", sum
if (op == "avg" || op == "all")
printf "The average is: %15.2f\n", sum/NR
}