この awk ワンライナーは私にとってはうまくいくようです:
[ghoti@pc ~]$ awk 'prev!=$2{first=0;prev=$2} {$1=first;first++} 1' input.txt
0 1 a
1 1 b
2 1 d
3 1 d
0 2 g
1 2 a
0 3 b
1 3 d
0 4 d
0 5 g
1 5 g
スクリプトを分解して、その機能を見てみましょう。
prev!=$2 {first=0;prev=$2}
-- これは、カウンターをリセットするものです。の初期状態prev
は空であるため、入力の最初の行でリセットしますが、これで問題ありません。
{$1=first;first++}
-- すべての行について、最初のフィールドを設定し、最初のフィールドを設定するために使用している変数をインクリメントします。
1
-- これは awk の「print the line」の省略形です。これは実際には常に「true」と評価される条件であり、条件/ステートメントのペアにステートメントがない場合、ステートメントはデフォルトで「print」になります。
本当に基本的なことです。
もちろん、1 つのキャッチは、awk の任意のフィールドの値を変更すると、設定されているフィールド セパレータを使用して行が書き換えられることです。これは、デフォルトでは単なるスペースです。これを調整したい場合は、OFS
変数を設定できます。
[ghoti@pc ~]$ awk -vOFS=" " 'p!=$2{f=0;p=$2}{$1=f;f++}1' input.txt | head -2
0 1 a
1 1 b
味に塩。