同じ数字を持つすべての行で数字を増やす方法

同じ数字を持つすべての行で数字を増やす方法

サンプルファイルは次のとおりです。

test test test test test
TEST: 15000
abcabc TEST: 15000 testtest test
TEST: 15000
test test  test 14000 test test test
TEST: 15000
TEST: 15000

15000が表示されている場合は、テキストが何であれ必要があります。各行に1を追加するだけです。

test test test test test
TEST: 15001
abcabc TEST: 15002 testtest test
TEST: 15003
test test  test 14000 test test test
TEST: 15004
TEST: 15005

答え1

そしてperl

$ cat file
TEST: 15000
TEST: 15000
TEST: 15000 15000 -15000 015007 15000e-1 1.15000
OTHER: 1000 1000 1000
AND: 1000 1000 0x14999 14999
$ perl -pe 's{\d+}{$& + ++$c{$&}}ge' file
TEST: 15001
TEST: 15002
TEST: 15003 15004 -15005 15008 15006e-2 3.15007
OTHER: 1001 1002 1003
AND: 1004 1005 1x15000 15001
$ perl -pe 's{\d+}{$& + $c{$&}++}ge' file
TEST: 15000
TEST: 15001
TEST: 15002 15003 -15004 15007 15005e-1 2.15006
OTHER: 1000 1001 1002
AND: 1003 1004 0x14999 15000

10進数シーケンスのみを処理します。したがって、入力が正の10進整数ではない場合、上記のように期待した結果が得られない可能性があります。

上記の015000はまだ10進数(8進数ではない)と見なされますが、比較が数字ではない語彙であるため、15000と同じと見なされません。数値比較の$c{$&}ために次のように置き換えます(各一意の数値の増分を記憶する$c{0+$&}連想配列のキーとして使用される数値を正規化することによって)。%c

すべての数字を区別することが目的であれば、そうしないことに注意してください。 15000 の最初の発生がどのように上から 14999 の 2 番目の発生と同じ数に変換されるかを確認します。

また、2 64 - 1(18446744073709551615)より大きい数字は科学的表記法で表され、精度が低下します。 Addは-Mbignumランダムに大きな数を処理できますが、タスクに1を挿入してbignumに変換する必要があります。

$ perl -pe 's{\d+}{$& + ++$c{$&}}ge' <<< 99999999999999999999
1e+20
$ perl -Mbignum -pe 's{\d+}{0 + $& + ++$c{$&}}ge' <<< 99999999999999999999
100000000000000000000

答え2

$ awk '{$2 += ++i}1' test.txt 
TEST: 15001
TEST: 15002
TEST: 15003

増加さiせてに追加します$2

ところで、変数がi最初にインクリメントされるときは存在しないので、初期値として生成され、次にインクリメント0されます。1 今後フィールド2に追加されます。代わりi++に に書いたならば++i増えたはずです。後ろに$2に初期値(0)が追加されます。

$2 = 15000 の場合のみ行数を増やすには、次のようにします。

awk '$2 == 15000 {$2 += ++i}1' test.txt 

または、perlを使用してperlの/e正規表現修飾子を使用して、s / /演算子のRHSをperl式として評価します。

TEST: 15000.5(例入力の末尾に行を追加しました)

$ perl -p -e 's/\d+/$& == 15000 ? $& + ++$i : $&/eg' input.txt 
test test test test test
TEST: 15001
abcabc TEST: 15002 testtest test
TEST: 15003
test test  test 14000 test test test
TEST: 15004
TEST: 15005
TEST: 15006.5

英語:連続した数字の数字が15000に等しい場合は、それ自体と事前に増分された変数に置き換え$i、それ以外の場合はそれ自体に置き換えます。

awkと同様に、$i存在しないときに使用すると初期値0(または文字列として使用する場合は空の文字列)として生成されます。ちなみに、これは変数名にスペルが間違っている(または変数が変数の範囲外で使用されている場合)、ランタイムエラーの非常に一般的な原因であるため、Perlにはすべての変数と他のuse strict識別子が必要なプラグマがあります。使用前の宣言。宣言されていない変数を使用すると、コンパイル時にエラーが発生するため、誤ったプログラムを実行して、損傷が発生する前にエラーを見つけて修正することができます。これは単純な1行であり、1つの変数だけを(一度だけ)使用するため、strictここでは使用しません。

または、可能であれば、15000.5入力に同様の数字がある可能性があります。いいえうまくいけば、彼らはまた増加します++$i

$ perl -p -e 's/(\d+)([^.])/($1 == 15000 ? $1 + ++$i : $1) . $2/eg' input.txt
test test test test test
TEST: 15001
abcabc TEST: 15002 testtest test
TEST: 15003
test test  test 14000 test test test
TEST: 15004
TEST: 15005
TEST: 15000.5

このバージョンは、2つのパターン、つまり数字(例:$ 1)と数字の後のすべての文字(例:$ 2)をキャプチャします。ただし、対応する文字は小数点(.)ではありません。カンマなどを使用するロケールでは、これを変更する必要があります。一致が成功すると、最初のPerlバージョンと同じように置換が計算されますが、.Perlの文字列連結演算子()を使用して$ 2が追加されます。

関連情報