sed/awk で一致した数値を検索/置換して増分する方法は? 質問する

sed/awk で一致した数値を検索/置換して増分する方法は? 質問する

端的に言うと、grep/find/sed/awk を使用して特定の文字列 (数字で終わる文字列) を一致させ、その数字を 1 ずつ増やす方法を知りたいです。私がこれまでに試した中で最も近い方法は、末尾に 1 を連結することです (これで十分です)。主なポイントは、単に値を変更することです。現在私が行っていることは次のとおりです。

find . -type f | xargs sed -i 's/\(\?cache_version\=[0-9]\+\)/\11/g'

数字を増やす方法がわからなかったので、全体をキャプチャして「1」を追加しました。以前は、次のようなものでした。

find . -type f | xargs sed -i 's/\?cache_version\=\([0-9]\+\)/?cache_version=\11/g'

だから、少なくとも必要なものをキャプチャする方法は理解しています。

これが何のためにあるのかを説明する代わりに、私がこれをどうしたいのかを説明します。これは、現在のディレクトリ (重要ではありません。任意のディレクトリでよいので、後で設定します) に基づいて、任意のファイル内で、数値を持つ "?cache_version=" に一致するテキストを再帰的に検索します。次に、その数値を増分して、ファイル内で置き換えます。

現時点では、上記のものは機能していますが、最後に見つかった数字を増やすことができません。将来の値が「11」、「111」、「1111」、「11111」などにならないように、「1」を追加するのではなく、増やすことができればもっと良いでしょう。

私は何十もの記事や説明を読んできましたが、多くの場合、 を使用することが提案されていますawkが、どうしてもそれらを混在させることはできません。 を使用することに最も近いのはawk、実際には何も置き換えない です。

grep -Pro '(?<=\?cache_version=)[0-9]+' . | awk -F: '{ print "match is", $2+1 }'

sed最後に をパイプして元のファイル名を渡し、sedファイル名と増分番号 ( からawk)、または必要なものを取得できる方法があるのか​​疑問に思っていますxargs

技術的には、この数字は重要ではありません。この置き換えは主に、新しい数字がそこにあり、前の数字とは 100% 確実に異なることを確認するためのものです。そのため、この質問を書いているときに、システム時間 (エポックからの秒数) を使用する方がよいことに気付きました (これは、後続の「同一」リクエストのキャッシュをなくすために AJAX でよく使用される手法です)。最終的に次のようになりましたが、これは完璧です。

CXREPLACETIME=`date +%s`; find . -type f | xargs sed -i "s/\(\?cache_version\=\)[0-9]\+/\1$CXREPLACETIME/g"

(何らかの理由で数秒に及ぶ場合に備えて、最初に値を保存するので、すべてのファイルで同じ値が取得されます)

しかし、一致した番号を増やすという元の質問が知りたいです。簡単な解決策は bash スクリプトにすることだと思いますが、それでも、一致した番号を増やすだけなので、すべてのファイルを再帰的にループして、その内容が一致するかどうかをチェックし、置換するよりも簡単な方法があると思いました。他のロジックはあまりありません。他のファイルなどに書き込みたくないだけです。sed"i" オプションのように、その場で実行する必要があります。

ベストアンサー1

ファイルを探すのはそれほど難しいことではないと思います。そこで、+1の計算をします。GNU セッド次のように実行できます。

sed -r 's/(.*)(\?cache_version=)([0-9]+)(.*)/echo "\1\2$((\3+1))\4"/ge' file

例を見てみましょう:

kent$  cat test 
ello
barbaz?cache_version=3fooooo
bye

kent$  sed -r 's/(.*)(\?cache_version=)([0-9]+)(.*)/echo "\1\2$((\3+1))\4"/ge' test     
ello                                                                             
barbaz?cache_version=4fooooo
bye

必要に応じて -i オプションを追加することもできます。

編集

/e一致した部分を外部コマンドに渡し、実行結果で置換することができます。Gnu sed のみ。

この例を参照してください: 外部コマンド/ツールechobc使用されています

kent$  echo "result:3*3"|sed -r 's/(result:)(.*)/echo \1$(echo "\2"\|bc)/ge'       

出力は次のようになります。

result:9

cut、sed (再び)、awk などの他の強力な外部コマンドを使用することもできます...

おすすめ記事