順次置換パターンに対する awk クエリ

順次置換パターンに対する awk クエリ

ファイルの特定の行を順番に置き換える次のawkコマンドを見つけましたが、これがどのように機能するかを知りたいです。

入力する:-

DS: 1
DS: 1
DS: 1
DS: 1
DS: 1
DS: 1
DS: 1

出力:-

DS: 1
DS: 2
DS: 3
DS: 1
DS: 2
DS: 3
DS: 1
DS: 2
DS: 3

awkコマンド:-

awk '$1 ~ /DS:/ {$NF=((c++ % count) + 1)} 1' count=3

答え1

awk私はその作業コマンドが次のように信じる理由があります。

awk -v count=3 '/DS:/ {$NF=((c++ % count) + 1)} 1' input

input入力ファイルはどこにありますか?また、質問で指定された出力を生成するには、入力ファイルに7行ではなく9行が必要です。

仕組みは次のとおりです。

まず、オプションが割り当て-v count=3られます3awk変える count。質問のように書かれている場合(count=3コマンドの最後)3に割り当てられます。シェル変数にアクセスできず、暗黙的に初期化されているため、ゼロ除算awkエラーが発生します。count0

存在する

/DS:/ {$NF=((c++ % count) + 1)}

この/DS:/部分が中かっこで囲まれたブロックの条件です。これは正規表現を表し、DS:文字列のみを一致させることができますDS:。この条件は含まれているすべての行と一致しますDS:

これらすべての行に対して変数がc増加し、次にモジュロに増加しますcount。この変数は明示的に定義されていないため、このコードブロックが最初に実行されたときに値cで暗黙的に初期化されます。0

その後、結果がに追加され割り当て1られます$NF。ここでは、NFフィールド区切り文字で区切られた行のフィールド数です。デフォルトのフィールド区切り文字(FS)は空白です。スペースはFS特別な場合awkであり、連続する複数のスペースは1つのフィールド区切り文字として扱われます。

NFフィールド数なので、最後の$NFフィールドを参照します。この場合、ペアの割り当ては評価から得られた値に置き換え$NFられます。1((c++ % count) + 1)

Final は1真の条件を表し、その後のコードブロックは省略されます。print条件が真の場合、その効果は暗黙的です。これは常に真であるため、1これは常に実行され、おそらく最後のブロック切り替え後に現在の行が印刷されます。

プロセスをよりよく理解するために追跡できますawkawk入力ラインを繰り返す暗黙のループがあります。

  • 行1:c暗黙的な割り当て0c++それでもですが、isモジュールに0変更され、is、isに変更され、割り当ては最終フィールド(この場合は最後の文字でもあります)をに変更して最終的にこの行を印刷するためです。c1(c++ % count)030((c++ % count)+1)111DS: 1

  • 2行目:c1((c++ % count)+1)2変更されます。最後のフィールドがに変更されて印刷されるので、を取得します。c22DS: 2

  • 3行目:同様にに((c++ % count)+1)変更して評価します。私達は得た 。c33DS: 3

  • 行4:今%実際に施行される時です。はモジュロとみなされ、(c++ %count)と同じで再評価されます。私達は得た 。330((c++%count)+1)1DS: 1

など。これがうまくいく方法です。行がない場合はDS:そのまま印刷されます。

関連情報