ファイルの特定の行を順番に置き換える次の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
られます3
。awk
変える count
。質問のように書かれている場合(count=3
コマンドの最後)3
に割り当てられます。シェル変数にアクセスできず、暗黙的に初期化されているため、ゼロ除算awk
エラーが発生します。count
0
存在する
/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
これは常に実行され、おそらく最後のブロック切り替え後に現在の行が印刷されます。
プロセスをよりよく理解するために追跡できますawk
。awk
入力ラインを繰り返す暗黙のループがあります。
行1:
c
暗黙的な割り当て0
。c++
それでもですが、isモジュールに0
変更され、is、isに変更され、割り当ては最終フィールド(この場合は最後の文字でもあります)をに変更して最終的にこの行を印刷するためです。c
1
(c++ % count)
0
3
0
((c++ % count)+1)
1
1
1
DS: 1
2行目:
c
今1
。((c++ % count)+1)
に2
変更されます。最後のフィールドがに変更されて印刷されるので、を取得します。c
2
2
DS: 2
3行目:同様にに
((c++ % count)+1)
変更して評価します。私達は得た 。c
3
3
DS: 3
行4:今
%
実際に施行される時です。はモジュロとみなされ、(c++ %count)
と同じで再評価されます。私達は得た 。3
3
0
((c++%count)+1)
1
DS: 1
など。これがうまくいく方法です。行がない場合はDS:
そのまま印刷されます。