awk /pattern/ { print "text"} /pattern/ {print ""} を使用するときに ELSE モードはありますか?

awk /pattern/ { print "text"} /pattern/ {print ""} を使用するときに ELSE モードはありますか?

次のテキストファイルがあるとしましょう。

R1 12 324 3453 36 457 4 7 8
R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242

awkこの行を別の方法で処理したいと思います。

awk '/R1/ { print "=>" $0} /R2/ { print "*" $0} '

また、残っているすべての行をそのまま印刷したいです(すでに処理した行を繰り返さずに)。デフォルトでは、 /ELSE/ { print $0}行の末尾に1つを追加する必要がありますawk

そんなことありますか?

答え1

簡素化されたアプローチawk

awk '/R1/ {print "=>" $0;next} /R2/{print "*" $0;next} 1' text.file

[jaypal:~/Temp] cat text.file 
R1 12 324 3453 36 457 4 7 8
R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242

[jaypal:~/Temp] awk '/R1/ { print "=>" $0;next} /R2/{print "*" $0;next}1' text.file
=>R1 12 324 3453 36 457 4 7 8
*R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242
[jaypal:~/Temp] 

パターン{Action}お問い合わせの画期的な進歩:

  • /R1/ { print "=>" $0;next}/R1/印刷ジョブを含む行が実行されることを示します。これは、awkステートメントの残りの部分が無視され、次の行がレビューされることを意味します。=>next

  • /R2/{print "*" $0;next}: これは、pattern /R2/印刷ジョブに一致する行が実行されることを意味します。処理が始まる*と、awk最初のpattern {action}文は無視されます。これで2番目のドアが完了します。これは、もはや処理を必要とせず、適切に次の行に移動することを意味します。pattern /R1//R2/pattern {action}nextawk

  • 1すべての行を印刷します。条件が指定されていない場合、{action}awkはデフォルトでusingを使用します{print}。ここの条件は1trueと解釈されるので、常に成功します。この点に達すると、最初と2番目のステートメントは無視または無視されるためです(およびをpattern {action}含まない行の場合)。したがって、基本印刷ジョブは残りの行で行われる。/R1//R2/

答え2

awk条件文で一般的な疑いを実装します。試合で達成したいもののprintf代わりに使用するのが最善です。print

awk '{ if (/^R1/) { printf("=> %s\n", $0) } else if (/^R2/) { printf("* %s\n", $0) } else { print $0 } }'

答え3

Chris Downは、ブロック内で明示的な「if」ステートメントを使用して正規表現のelseを取得する方法を示しました。同じ効果を得る他の方法もありますが、彼の解決策はより良いかもしれません。

1つは、一致しないテキストにのみ一致する3番目の正規表現を作成することです。あなたの場合は次のとおりです。

awk '/^R1/ { print "=>" $0}
     /^R2/ { print "*" $0}
     /^[^R]/ || /^R[^12]/ { print $0 } '

これは固定正規表現を使用することに注意してください。正規表現の先頭の^は行の先頭でのみ一致します。元のパターンはこれを実行せず、代わりに行内のすべての文字をチェックするので、一致が少し遅くなります。次の行にジャンプします。 3番目( "else")の場合は、 "R"([^ R])以外の文字で始まる行または "R"で始まり、後に "1"または ""以外の文字が続く行と一致します。 2'(R[^12])。 ^の2つの異なる意味は少し混乱しています。しかし、この間違いはずっと前に発生し、近い将来変わりません。

補完的な正規表現を使用するには固定する必要があります。そうでなければ、[^R]はそれに続く1に一致します。この方法はあなたのように非常に単純な正規表現に役立ちますが、正規表現がより複雑になると、この方法を管理するのが難しくなります。代わりに、次のように各行に状態変数を使用できます。

awk '{ handled = 0 }
     /^R1/ { print "=>" $0; handled = 1}
     /^R2/ { print "*" $0; handled = 1}
     { if (!handled) print $0 } '

これにより、各新しい行の処理が0に設定され、2つの正規表現のいずれかと一致する場合は1に設定され、最後にまだ0の場合は$ 0が印刷されます。

関連情報