一致する行の最初の項目をすべて増分数字に置き換えるには?

一致する行の最初の項目をすべて増分数字に置き換えるには?

このようなファイルがあります。

...
1562 first part
1563 H     col3 H col4
1564 H     col3 H col4
...
3241 H     col3 H col4
3242 third part
...

H各行の最初の行をそのH#発生#回数に置き換えたいと思います。出力は次のようになります。

...
1562 first part
1563 H1    col3 H col4
1564 H2    col3 H col4
...
3241 H1652 col3 H col4
3242 third part
...

これまで私は次のことを試しました。

max=`grep -c ' H ' b`
while [[ "$i" -le $max ]];do
  grep -m $i ' H ' b|tail -n1|sed "s/H/H$i/1"
  let i=i+1
done

このコードは遅く、置き換えるすべての行を読み取る必要があり、ファイルの最初の部分と3番目の部分を追加することはできません。これを行うより良い方法はありますか?たぶんちょっと?ありがとうございます。

答え1

たとえば、次のように使用できます。

$ awk '/H/{sub("H", "H"++v)}1' file
1562 first part
1563 H1     col3 H col4
1564 H2     col3 H col4

3241 H3     col3 H col4
3242 third part
...

その後、それを含む行を見つけて増え続けるH変数に置き換えます。単一のパターンではなく、一致するすべてのパターンでこの変更を実行したい場合は、代わりに使用できます。HHgsub()sub()

最後の条件1はtrue条件なので、デフォルトのawkジョブである行{print $0}全体を印刷することを行います。

答え2

この試み:

  awk 'BEGIN { hNum = 1; } { if ($2 == "H") { $2 = "H" hNum; hNum++; } print $0; }' yourFile > outFile

各行の 2 番目のトークンと同様に、awkスペースを区切り文字として使用し、「H」と等しい場合は「H」と 1 から始まる数字に置き換えます。最後にラインを印刷します。$2$2

答え3

そしてperl

perl -pe 's/\bH\b\K/++$i/e' file

内部編集に-pe置き換えたり、元のファイルをバックアップとして保存したり保存したりすることはできません。-pi.back -efile.back-pi -e

答え4

{   nl -bpH -w1 |
    sed 's/^\([0-9]*\)[ \t]*\([^H]*.\)/\2\1/'
} <<\DATA
...
1562 first part 
1563 H     col3 H col4
1564 H     col3 H col4
...
3241 H     col3 H col4
3242 third part
DATA

出力

...
1562 first part 
1563 H1     col3 H col4
1564 H2     col3 H col4
...
3241 H3     col3 H col4
3242 third part

これは私が想像できる最速の方法です。特に非常に大きなファイルの場合はさらにそうです。nl文字列を含む行に番号だけを付ける時間そして、行の先頭に対応する数字を挿入し、その後に<tab>1文字を挿入します。他のすべての行は少し空白だけインデントされます。

sednl出力はパイプを通過しました|sed次に、次の順序を置き換えます。

  • 行の先頭にゼロ個以上の数字が表示されます。(として引用\1
  • 0個以上<tab>または<space>文字
  • H以外の0文字以上、次の1文字(として引用\2

...そして\2\1

したがって、以下を含まない行は時間次の治療を受けてください。

^''   .*.$ = ^.*.''$

これを得る人は次のとおりです。

^(digit)*<tab>(not H)*H.*$ = ^(not H)*H(digit)*.*$

...''空の文字列があります。

移植性を最大化するには、\tinを[ \t]リテラル<tab>文字に置き換える必要があります。

関連情報