サンプルファイルは次のとおりです。
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が追加されます。