AWK:正規表現を使用して2つの変数を比較する方法

AWK:正規表現を使用して2つの変数を比較する方法

コロンで区切られた値行があり、これを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文字列の残り:

最初は一致しますが、2番目は一致しません。

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

/^$2/テキストを含み、行末アンカーである$2正規表現として扱われます。$EOL以降は何も所有できないため、REは決して一致しません。

答え2

/^$3/正規表現です絶対一致しない保証3レコード終了後のレコードと一致するため($正規表現アンカー演算子はトピックの終わりと一致します$ awk。数値でフィールドを逆参照するために使用される演算子と混同しないでください。

3番目のフィールドが4番目のフィールドの先頭に表示されるかどうかをテストするには、を使用して正規表現の一致を実行できます。match()これにより、一致の開始位置が返されます(一致がない場合は-1)。

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

または文字列比較の場合

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

関連情報