web-dev-qa-db-ja.com

キャプチャグループを維持しながらRegEx with / grepおよびsedで再帰的に置き換えますか?

長いタイトルです。基本的に、私が持っているのは、正規表現で再帰的に検索して置換する必要があるファイルのコレクションです。

これまでのところ、キャプチャグループがなくても機能しますが、使用しても何も起こりません。 別の質問 で見つけたコマンドを現在使用しています:

grep -rlP "/\* *(\d+) *\*/ (.*)" . | xargs sed -i "s/\/\* *(\d+) *\*\/ (.*)/$2 \/\/ JD $1/g"

この正規表現は、エスケープされたアスタリスクとスラッシュを多く含んでいるため、非常に混乱しますが、基本的には文字列を受け取ります(たとえば)

/*  73 */   private static int last = -1000;

そしてそれを

private static int last = -1000; // JD 73

ただし、前述したように、それは単に機能せず、ファイルは変更されません。

キャプチャグループを使用しない代替正規表現で正常に動作します

grep -rl "/\* *\*/ " . | xargs sed -i "s/\/\* *\*\/ //g"

しかし、キャプチャグループを導入しようとすると、ただ黙って失敗します。

成功したドライブと同様にドライブが少しの間スピンアップするのを聞くことができるので、ファイルを検索していることがわかりますが、最終的にファイルは変更されません。

コマンドが機能するように変更することは可能ですか、それともまったく異なる方法で行う必要がありますか?また、理想的には、ソリューションはbashループを必要としないでしょう。ありがとう。

2
SirNapkin1334
  • grep-P-Eに置き換え、[[:digit:]]の代わりに[0-9]+または(\d+)を使用します。これは、他のPerl互換を使用しないためです。かっこは必要ありません
  • grepから(.*)を削除します。これは冗長です
  • -Esedに追加するか、キャプチャグループ(...)+をエスケープする必要があります
  • セドは\d+を理解できません。[[:digit:]]または[0-9]+に置き換えてください
  • 後方参照$1\1に、$2\2に置き換えます
  • gを安全に削除できると思います。JDは行の先頭にコメントを1つだけ作成します。
grep -Erl '/\* *[[:digit:]]+ *\*/' . |
  xargs sed -Ei 's/\/\* *([[:digit:]]+) *\*\/ (.*)/\2 \/\/ JD \1/'
4
Freddy

sedでは、キャプチャされたグループは\1\2などではなく$1$2などで参照されます。「 Back_002dreferences-」を参照してください。 and-Subexpressions.html

1
simonz

この例のように、sedのみを使用します

echo "/*  73 */   private static int last = -1000;" | 
    sed 's#^/\*[[:blank:]]*\([0-9]*\)[[:blank:]]*\*/[[:blank:]]*\(.*\)$#\2 // JD \1#g'
private static int last = -1000; // JD 73