파이핑 후 스크립트 변수를 AWK에 전달

파이핑 후 스크립트 변수를 AWK에 전달

내가 작성한 스크립트에서 변수 할당에 문제가 있습니다 awk. 명령 은 awk함수 내부에 있으며 세 개의 변수가 스크립트의 다른 위치에서 함수에 전달됩니다. 나는 이전에 awkVariables: to break the command 를 사용하여 이 작업을 수행한 적이 있지만 awk ... '"$var"' ...분명히 이것은 다소 엉성한 접근 방식이며 awk스위치를 통해 변수를 할당할 수 있습니다 -v.

이것이 내가 하고 싶은 일이다:

my_function() {
  command1 \
  | command2 \
  | awk -v var1="$1" -v var2="$2" -v var3="$3" '{
                FS="[ ,\"]+"}/var1=/{
                        for ( i=2; i<NF; i++) {
                                        if ( var2 ){
                                                var3; next;
                                        }
                                }
                        }
                {
                        fname=$0
        }'
}

...

my_function "$firstArg" "$secondArg" "$thirdArg"

using의 출력에 따르면 awk 명령 시작 부분에서 변수 할당이 올바르게 발생하지만 명령은 이 방식으로 수행하는 대신 아무 것도 반환하지 않으므로 제대로 작동한다는 것을 set -x알 수 있습니다 .awkawk ... '"$var"' ...

여기에 뭔가 빠진 것 같은 느낌이 듭니다.

답변1

다음과 같은 작업을 수행하려는 것 같습니다.

my_function() {
    command1 |
    command2 |
    awk -v var1="$1" -v var2="$2" -v var3="$3" '
        BEGIN { FS="[ ,\"]+" }
        $0 ~ (var1"=") {
            for ( i=2; i<NF; i++) {
                if ( $0 ~ var2 ) {   # maybe just "if (var2)", depends on context
                    var3        # NOTE: this line does nothing
                    next
                }
            }
        }
        { fname=$0 }      # NOTE: this is populating a variable thats never used.
    '
}

...

my_function "$firstArg" "$secondArg" "$thirdArg"

예, awk ... '"$var"' ...정말 끔찍해요. 고려하다:

$ var=$(printf 'a\nb')
$ echo "$var"
a
b

명백하고 이상적인 출력:

$ awk -v foo="$var" 'BEGIN{print foo}'
a
b

흐릿하고 원치 않는 출력:

$ awk 'BEGIN{print '"$var"'}'

$ awk 'BEGIN{print "'"$var"'"}'
awk: cmd. line:1: BEGIN{print "a
awk: cmd. line:1:             ^ unterminated string
awk: cmd. line:1: BEGIN{print "a
awk: cmd. line:1:             ^ syntax error
$

바라보다awk 스크립트에서 쉘 변수를 사용하는 방법awk 스크립트에서 쉘 변수 값을 사용하는 다양한 방법에 대한 완전한 토론입니다. -v쉘 변수의 내용에 따라 using이 잘못된 접근 방식일 수 있으며 ENVIRON[]or를 사용하는 ARGV[]것이 더 나을 수도 있습니다.

질문의 스크립트에서 하신 방법은 입력 행마다 한 번씩 설정하라고 했는데 이미 행이 분할된 후에는 설정한 FS가 첫 번째 입력 행에 적용되지 않아서 {FS="[ ,\"]+"}으로 변경했습니다 . BEGIN{FS="[ ,\"]+"}총 한 번이 아닌 행당 한 번씩 설정하는 것입니다. 차이점을 살펴보세요.

$ printf 'a,b\nc,d\n' | awk '{FS=","} {print $1}'
a,b
c

$ printf 'a,b\nc,d\n' | awk 'BEGIN{FS=","} {print $1}'
a
c

var3;당신이 무엇을 하려는지는 분명하지 않지만 , 그것이 무엇을 하는지는 - 아무것도 아닙니다.

코드 구조가 프로그램의 제어 흐름을 반영하도록 어떻게 줄바꿈을 들여쓰고 사용하는지 주목하세요. 귀하의 질문에 있는 코드의 들여쓰기 등은 그렇게 하지 않으므로 코드를 혼란스럽게 합니다. 나중에 위에 표시한 스타일로 코드를 구성해 보고 gawk -o-방법이 확실하지 않은 경우 실행하여 좋은 프린트가 그것을 구축합니다.

관련 정보