AWK: 정규식을 사용하여 두 변수를 비교하는 방법

AWK: 정규식을 사용하여 두 변수를 비교하는 방법

콜론으로 구분된 값 행이 있는데 이를 awk에서 처리하고 싶습니다. 행 의 시작 부분에 변수가 포함되어 있으면 $4행이 다르게 처리됩니다 .$3

그래서 저는 다음과 같은 표현을 썼습니다. $4 ~ /^$3/그러나 불행하게도 이것은 작동하지 않으며 결코 일치하지 않습니다. 안녕하세요, 정규식 패턴에서 변수를 사용하는 방법은 무엇입니까?

전체 예는 다음과 같습니다.

green="$(tput setaf 2)"
red="$(tput setaf 1)"
yellow="$(tput setaf 3)"
normal="$(tput sgr0)"

stacks=$(docker stack ls --format='{{.Name}}')

for stack in ${stacks}; do
    status=$(docker stack ps --filter="desired-state=running" --format="{{.Name}}:{{.Node}}:{{.DesiredState}}:{{.CurrentState}}:{{.Error}}" ${stack})
    if test -z "$status"; then
        echo "${red}$stack$: disabled${normal}"
    else
        awk -F: '                                                                            
            $4 ~ /^$3/ {print "GOOD '"${green}"'" $1 ": " $4 "'"${normal}"'"}                
            $4 !~ /^$3/ {print "BAD '"${yellow}"'" $1 ": " $3 " ≠ " $4 $5 "'"${normal}"'"}   
        ' <<<${status}
    fi
done

결과는 항상 다음과 같습니다 BAD. 예를 들어 여기에서는 다음과 같습니다.

bind_bind.1:urknall:Running:Running 18 hours ago:

인쇄해야 GOOD하지만 대신 다음을 인쇄합니다.

BAD bind_bind.1: Running ≠ Running 18 hours ago

답변1

문자열에서 a 오른쪽에 정규식을 넣을 수 있습니다 ~. 구문일 필요는 없습니다 /.../. (차이점은 런타임이나 컴파일 타임에 RE를 구문 분석하는 것과 관련이 있을 수 있지만 확실하지 않습니다.) awk달러 기호는 셸이나 Perl에서처럼 변수 확장을 의미하지 않으므로 연결해야 한다는 점을 명심하세요. $3문자열에 나머지:

첫 번째는 일치하지만 두 번째는 일치하지 않습니다.

$ echo 'foo fo+' |awk '$1 ~ "^" $2'
foo fo+
$ echo 'foo o+' |awk '$1 ~ "^" $2'
$

/^$2/텍스트를 포함하고 줄 끝 앵커인 $2정규식 으로 처리됩니다 . $EOL 이후에는 아무것도 소유할 수 없으므로 RE는 절대 일치할 수 없습니다.

답변2

/^$3/정규 표현식입니다절대 일치하지 않음 보장3레코드 끝 이후의 레코드 와 일치하기 때문에 ( $정규식연산자는 주제의 끝과 일치합니다 $ awk. 숫자로 필드를 역참조하는 데 사용되는 연산자와 혼동하지 마십시오.

세 번째 필드가 네 번째 필드의 시작 부분에 나타나는지 테스트하려면 를 사용하여 정규식 일치를 수행할 수 있습니다. match()그러면 일치 항목의 시작 위치가 반환됩니다(또는 일치 항목이 없으면 -1).

awk -F ':' 'match($4, $3) == 1 { ..."GOOD"... ; next } { ..."BAD"... }'

또는 문자열 비교의 경우

awk -F ':' 'substr($4, 1, length($3)) == $3 { ..."GOOD"... ; next } { ..."BAD"... }'

관련 정보