简体   繁体   中英

How can i change an Ant grep to have unix style “or” in its regular expression?

I have the following code for grepping an xml file repo, in ant :

<echo message="Now checking xml test results for errors"    />
        <exec executable="grep" error="/dev/null">
            <arg value="-r" />
            <arg value="-m" />
            <arg value="1" />
            <arg value="-rl" />
            <arg value="errors=\&quot;[1-9]\&quot;" /> 
            <arg value="${reports.dir}" />
        </exec>
    <fail if="junit.failed" message="FAILING - unit tests failed." />

Im trying to replace :

   <arg value="errors=\&quot;[1-9]\&quot;" /> 

with something along the lines of :

   <arg value="errors|failures=\&quot;[1-9]\&quot;" /> 

So that both errors AND failures will be caught. How can I encode the grep correctly in my Ant XML to reflect this ? "**grep -r -m 1 -rl errors|failures=\\"[1-9]\\" ../reports/**" does not do the trick ( it results in a syntax issue, breaking the standard grep parser i guess )...

This is a guess, but you could try something along the lines of:

<arg value="-e" />
<arg value="errors=\&quot;[1-9]\&quot;" />
<arg value="-e" />
<arg value="failures=\&quot;[1-9]\&quot;" />

From man grep :

   -e PATTERN, --regexp=PATTERN
          Use PATTERN as the pattern; useful to protect patterns beginning with -.

You could do this in a platform-independent way using an Ant filterchain instead of executing grep.

The following example filters every file under report.dir for the regex, with a head filter to short-circuit when a single match is found. The result output is loaded into a property.

  <target name="test">
    <loadresource property="junit.failed">
      <concat>
        <fileset dir="${report.dir}">
          <include name="**/*"/>
        </fileset>
        <filterchain>
          <linecontainsregexp>
            <regexp pattern="failures|errors=\&quot;\d+\&quot;"/>
           </linecontainsregexp>
           <headfilter lines="1"/>
        </filterchain>
      </concat>
    </loadresource>
    <fail if="junit.failed" message="FAILING - unit tests failed"/>
  </target>

One thing you cannot achieve using this technique is to get the names of matching files (which grep -l gives you) rather than the matching lines. However, you are not using the file names in your example.

Note also that the regex you are using in your grep will not find errors and failures greater than 9, eg errors="11" will not be found. The pattern in the example above does find these.

Pipe does not work for you because it is interpreted by shell as a shell's pipe instead of the regex element. To improve the situation you should put the parameter into quotes.

grep -r -m 1 -rl "errors|failures=\\"[1-9]\\"" ../reports/**"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM