需要匹配Sed表达式中的两个组

时间:2013-01-03 11:25:26

标签: regex sed

这类似于Using sed to replace beginning of line when match found但是一个不同的问题因此这个线程。

我希望取消注释掉已注释掉的代码。更具体地说,所有变量myVar被注释掉的情况。

示例:

public class MyClass {
   ...
   ...
   //myVar.setAge(200);
   //myVar.setPlanet("mars");
}

public class MyClass {
   ...
   ...
   myVar.setAge(200);
   myVar.setPlanet("mars");
}

正则表达式:

^\\.*myVar.*$

获取我需要的一切。

棘手的部分是获得正确的Sed。我试试:

sed 's/(^\\)(.*myVar.*$)/\2/g' Build_DM_Digests_Batch.cls

在以下基础上。创建两个匹配组。第一个是注释掉的行。第二个是其余部分。仅使用第二个mateched组替换整行。

这会出错:

sed: -e expression #1, char 29: Unmatched ) or \)

任何提示?

3 个答案:

答案 0 :(得分:2)

使用sed 's/^\( *\)\/\/\(.*myVar.*$\)/\1\2/' file

$ cat hw.java 
class hw {
    public static void main(String[] args) {
        System.out.println("Hello World!"); 
//        myVar=1
        //myVar.setAge(200);
        //myVar.setPlanet("mars");
    }
}

$ sed 's/^\( *\)\/\/\(.*myVar.*$\)/\1\2/' hw.java
class hw {
    public static void main(String[] args) {
        System.out.println("Hello World!"); 
        myVar=1
        myVar.setAge(200);
        myVar.setPlanet("mars");
    }
}

使用-i选项将更改保存在文件sed -i 's/^\( *\)\/\/\(.*myVar.*$\)/\1/' file中:

说明:

^      # Matches the start of the line
\(     # Start first capture group  
 *     # Matches zero or more spaces
\)     # End first capture group
\/\/   # Matches two forward slashes (escaped)
\(     # Start second capture group 
.*     # Matches anything 
myVar  # Matches the literal word 
.*     # Matches anything
$      # Matches the end of the line
\)     # End second capture group 

在这里,我们捕获//之前的空白,然后捕获行上myVar之后的所有内容,并替换为\1\2

你的逻辑几乎只有几个,首先是逃脱了所有括号,其次你想要^( *)\/\/而不是^\\这是两个转义的转发,并且在开始时捕获的空格不是两个反斜杠line:

如果您不想转义括号,则需要使用sed的{​​{1}}扩展正则表达式标记-r GNU sed OSX -E所以请查看sed --help

sed -r 's/^( *)\/\/(.*myVar.*$)/\1\2/' file

注意:当您匹配整行时(从^$),g标志是多余的。

答案 1 :(得分:0)

另一种方式:

sed 's!^\([ \t]*\)//\(.*\<myVar\>\)!\1\2!' input

答案 2 :(得分:0)

Chris' answer和说明有效。但是,我想添加一个更简洁的等效表达式。这种表达依赖于两个变化

  • 将分隔符更改为未包含在正则表达式中的任何字符,例如|,将摆脱/的转义字符
  • 指定扩展的正则表达式(-r)摆脱了括号()的转义符

这将导致可读的命令,其意图更清晰,更接近您的预期使用。

sed -r 's|^( *)//(.*myVar.*$)|\1\2|' filename