次のテキストファイルがあるとしましょう。
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}
next
awk
1
すべての行を印刷します。条件が指定されていない場合、{action}
awkはデフォルトでusingを使用します{print}
。ここの条件は1
trueと解釈されるので、常に成功します。この点に達すると、最初と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が印刷されます。