awk의 명령줄 매개변수

awk의 명령줄 매개변수

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


$1in 을 사용하면 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에 따르면문서, 인수는 다음과 같습니다.오직두 가지 형식 중 하나로 해석됩니다.

  1. 읽을 파일
  2. 과제 형식: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
}

관련 정보