多么长的标题啊。本质上,我拥有的是需要使用正则表达式递归搜索并替换的文件集合。
到目前为止,我所拥有的在没有捕获组的情况下也可以工作,但是在使用它们时它什么也不做。我目前正在使用我在上找到的命令另一个问题:
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
为-E
ingrep
并使用[[:digit:]]
or[0-9]+
代替,(\d+)
因为您不使用任何其他 Perl 兼容的东西并且不需要括号 (.*)
从 中删除grep
,这是多余的- 添加
-E
到sed
或者你必须逃离你的捕获组(...)
和+
- 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