在维护捕获组的同时递归地替换为带有 grep 和 sed 的正则表达式?

在维护捕获组的同时递归地替换为带有 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 循环。谢谢。

答案1

  • 替换-P-Eingrep并使用[[:digit:]]or[0-9]+代替,(\d+)因为您不使用任何其他 Perl 兼容的东西并且不需要括号
  • (.*)从 中删除grep,这是多余的
  • 添加-Esed或者你必须逃离你的捕获组(...)+
  • sed 不理解,用or\d+替换[[:digit:]][0-9]+
  • 将反向引用替换$1\1$2\2
  • 我认为你可以安全地删除g,JD 只在行的开头创建一个注释。

grep -Erl '/\* *[[:digit:]]+ *\*/' . |
  xargs sed -Ei 's/\/\* *([[:digit:]]+) *\*\/ (.*)/\2 \/\/ JD \1/'

答案2

在 中sed,捕获的组用\1,\2等引用,而不是$1,$2等。请参阅Back_002dreferences-and-Subexpressions.html

答案3

仅使用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

相关内容