Ant: get multiple matches with propertyregex - ant

I have these (sample) lines in a HTML-file:
test.ABC.test
test.ABCD.test
test.ABCE.test
And this Ant propertyregex:
<loadfile property="getRecords" srcFile="./index.html"/>
<propertyregex property="record" input="${getRecords}" regexp="test\.([^\.]*)\.test" select="\1" casesensitive="true" override="true" global="true" />
<echo message="${record}" />
The result is just
ABC
But I'd like to get all matches. How can I get
ABC
ABCD
ABCE
as result?

Not sure about the propertyregex problem, but this works (without ant-contrib):
<target name="test">
<loadfile property="record" srcFile="./index.html">
<filterchain>
<tokenfilter>
<containsregex pattern=".*test\.([^\.]*)\.test.*" replace="\1"/>
</tokenfilter>
</filterchain>
</loadfile>
<echo message="${record}" />
</target>

Related

Find the number of occurrences of a particular character like comma in a string using ant script?

<project>
<target name="test">
<property name="src.dir" value="src" />
<property name="search4" value=","/>
<fileset id="existing" dir="${src.dir}/src">
<patternset id="files">
<include name="*.txt"/>
</patternset>
</fileset>
<resourcecount property="count">
<fileset id="matches" dir="../src">
<patternset refid="files" />
<contains text="${search4}" />
</fileset>
</resourcecount>
<echo message="Found '${search4}' in files : '${count}'"/>
</target>
</project>
I used this, but this only prints the first occurrence. I would like to print the total count.
For eg - abc,xyz,pg--> The number of occurrences of commas(,) is 2.
Here's one way. Copies the file to another file, with a filter to remove all non-commas, then gets the size of the output, which is the number of commas in the input file.
<delete file="out.txt" />
<copy file="in.txt" tofile="out.txt">
<filterchain>
<striplinebreaks />
<replaceregex pattern="[^,]" replace="" flags="gm" />
</filterchain>
</copy>
<length file="out.txt" property="out.size" />
<echo message="Commas found: ${out.size}" />
On your follow up question: how to restrict this to just the first line of the file: add this before the "striplinebreaks" line:
<headfilter lines="1" />
That will count commas in just the first line of the file.

Resource Count in Ant Scripts

I just need to know how to modify the code below so that ant determines the number of lines in my text files (Please note all text files here will have same number of lines but that number is not fixed) and automatically executes them based on the loop.
<project name="ant-read-n-files" default="run" basedir=".">
<!-- Load the ant contrib lib -->
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="${basedir}/lib/ant-contrib.jar"/>
</classpath>
</taskdef>
<target name="read">
<!-- file a -->
<loadfile property="textFileA" srcfile="${basedir}/files/aaa.txt">
<filterchain>
<headfilter lines="1" skip="${linenum}"/>
</filterchain>
</loadfile>
<for param="line" list="${textFileA}" delimiter="${line.separator}">
<sequential>
<property name="textFileAValue" value="#{line}"/>
</sequential>
</for>
<!-- file b -->
<loadfile property="textFileB" srcfile="${basedir}/files/bbb.txt">
<filterchain>
<headfilter lines="1" skip="${linenum}"/>
</filterchain>
</loadfile>
<for param="line" list="${textFileB}" delimiter="${line.separator}">
<sequential>
<property name="textFileBValue" value="#{line}"/>
</sequential>
</for>
<!-- file c -->
<loadfile property="textFileC" srcfile="${basedir}/files/ccc.txt">
<filterchain>
<headfilter lines="1" skip="${linenum}"/>
</filterchain>
</loadfile>
<for param="line" list="${textFileC}" delimiter="${line.separator}">
<sequential>
<property name="textFileCValue" value="#{line}"/>
</sequential>
</for>
<!-- Print them all -->
<echo message="${textFileAValue}"/>
<echo message="${textFileBValue}"/>
<echo message="${textFileCValue}"/>
</target>
<target name="run">
<foreach param="linenum" list="0,1,2" target="read"/>
</target>
</project>
Here as you see list = "0,1,2" means the loop will verify first three lines of each text file, but i want this to be dynamic depending on the number of lines the files have.
Any help here would be greatly appreciated.
Thanks,
Ashley
The below solution works here:-
<project name="ant-read-n-files" default="run" basedir=".">
<!-- Load the ant contrib lib -->
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="${basedir}/lib/ant-contrib.jar"/>
</classpath>
</taskdef>
<target name="read">
<!-- file a -->
<loadfile property="textFileA" srcfile="${basedir}/files/aaa.txt">
<filterchain>
<headfilter lines="1" skip="${linenum}"/>
</filterchain>
</loadfile>
<for param="line" list="${textFileA}" delimiter="${line.separator}">
<sequential>
<property name="textFileAValue" value="#{line}"/>
</sequential>
</for>
<!-- file b -->
<loadfile property="textFileB" srcfile="${basedir}/files/bbb.txt">
<filterchain>
<headfilter lines="1" skip="${linenum}"/>
</filterchain>
</loadfile>
<for param="line" list="${textFileB}" delimiter="${line.separator}">
<sequential>
<property name="textFileBValue" value="#{line}"/>
</sequential>
</for>
<!-- file c -->
<loadfile property="textFileC" srcfile="${basedir}/files/ccc.txt">
<filterchain>
<headfilter lines="1" skip="${linenum}"/>
</filterchain>
</loadfile>
<for param="line" list="${textFileC}" delimiter="${line.separator}">
<sequential>
<property name="textFileCValue" value="#{line}"/>
</sequential>
</for>
<!-- Print them all -->
<echo message="${textFileAValue}"/>
<echo message="${textFileBValue}"/>
<echo message="${textFileCValue}"/>
</target>
<target name="run">
<!-- Get number of lines of one of the files -->
<loadfile property="textFile" srcfile="${basedir}/files/aaa.txt"/>
<resourcecount property="line.count" count="0" when="eq">
<tokens>
<concat>
<filterchain>
<tokenfilter>
<stringtokenizer delims="${line.separator}" />
</tokenfilter>
</filterchain>
<propertyresource name="textFile" />
</concat>
</tokens>
</resourcecount>
<echo message="Number of lines: ${line.count}" />
<script language="javascript">
var list="", n=parseInt(project.getProperty("line.count"), 0);
for (var i = 0; i < n; i++) list += i + ",";
project.setProperty("list", list);
</script>
<foreach param="linenum" list="${list}" target="read"/>
</target>
</project>

How to solve this ANT issue?

<loadfile property="UIfiles" srcfile="updated.txt">
<filterchain>
<linecontainsregexp>
<regexp pattern="ui/dev/"/>
</linecontainsregexp>
</filterchain>
</loadfile>
<echo file="Filelist.txt" append="true">${UIfiles}</echo>
I have the above code in build.xml file. updated.txt will contain some text like Projects/accounts/spec/ui/dev/dpdl/abc.xml. If this statement is present in the file, then the above code works as expected. If there is no match for regex "ui/dev" in updated.txt, ideally the value of UIfiles should be empty and should not write anything to Filelist.txt. But in my case "${UIfiles}" is getting appended in Filelist.txt. Please suggest how to avoid this. Thank you.
Works as expected. ${...} is the syntax for your property when not set, because
your file doesn't contain a line matching the regexp.
You need some if isset condition, with Ant 1.9.3 and new if unless feature :
<project
xmlns:if="ant:if"
xmlns:unless="ant:unless"
>
<loadfile property="UIfiles" srcfile="updated.txt">
<filterchain>
<linecontainsregexp>
<regexp pattern="ui/dev/"/>
</linecontainsregexp>
</filterchain>
</loadfile>
<echo file="Filelist.txt" append="true">${UIfiles} if:set="UIfiles"</echo>
</project>
otherwise for older Ant versions use:
<project>
<target name="checkfile">
<loadfile property="UIfiles" srcfile="updated.txt">
<filterchain>
<linecontainsregexp>
<regexp pattern="ui/dev/"/>
</linecontainsregexp>
</filterchain>
</loadfile>
</target>
<target name="appendfilelist" depends="checkfile" if="UIfiles">
<echo file="Filelist.txt" append="true">${UIfiles}</echo>
</target>
<project>

Want to remove [apply], [script] like keywords from file

I am using following code block:
<copy tofile="${dir.report}\${file.report.name}.html" file="${dir.report}\${file.report.name}.html">
<filterchain>
<tokenfilter>
<replaceregex pattern="\[(script|apply)\]" replace="" />
</tokenfilter>
</filterchain>
</copy>
But replaceregex is not working
Can someone help me out here.
This would be a simpler solution:
<copy tofile="build/input1.html" file="src/input1.html">
<filterchain>
<tokenfilter>
<replacestring from="apply" to=""/>
<replacestring from="script" to=""/>
</tokenfilter>
</filterchain>
</copy>
The <copy> task cannot "self-copy" files. The source file path has to be different than the destination file path.
Luckily, the <replaceregexp> task provides a simpler solution:
<replaceregexp file="${dir.report}\${file.report.name}.html" flags="g">
<regexp pattern="\[(script|apply)\]"/>
<substitution expression=""/>
</replaceregexp>

Replace property in a xml file using ANT

I'm trying to replace a version number in a build.xml file using an ANT script.
I've tried various approaches, searched and re-searched StackOverflow for answers but could not get the exact query.
so here is my xml file:
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<project name="feature" default="main" basedir=".">
<target name="init">
<property name="Version" value="1.0.0.20120327"/>
</target>
<target name="main" depends="init">
<description>Main target</description>
</target>
</project>
Now as u can see the Version has yesterday's date. I need to replace it with the current date.
Here is what I've tried:
<target name="replace">
<tstamp >
<format property="touch.time" pattern="yyyyMMdd"/>
</tstamp>
<property name="Feature.dir" location="../feature" />
<!--Didnt Work-->
<copy file="${Feature.dir}\build.xml" tofile="${Feature.dir}\build1.xml"
filtering="yes" overwrite="yes">
<filterset>
<filter token="Version" value="1.0.0.${touch.time}"/>
</filterset>
</copy>
<!--Didnt work
<replacetoken><![CDATA[<property name="Version" value=""/>]]>
</replacetoken>
<replacevalue><![CDATA[<property name="Version"value="1.0.0.${touchtime}" />]]>
</replacevalue>
-->
<!-- Didnt work
<copy file="${Feature.dir}/build.xml" tofile="${Feature.dir}/build1.xml" >
<filterchain>
<tokenfilter>
<replaceregex pattern="^[ \t]*Version[ \t]*=.*$"
replace="Version=1.0.0.${touch.time}"/>
</tokenfilter>
</filterchain>
</copy>
-->
</target>
I would use replaceregex inside a filterchain.
For example:
<copy file="${Feature.dir}\build.xml" tofile="${Feature.dir}\build1.xml"
filtering="yes" overwrite="yes">
<filterchain>
<tokenfilter>
<replaceregex pattern="1.0.0.[0-9.]*" replace="1.0.0.${touch.time}"/>
</tokenfilter>
</filterchain>
</copy>
If you want to replace the file, feel free to copy to a temp file and move it back.
<tempfile property="build.temp.file.name"/>
<copy file="${Feature.dir}\build.xml" tofile="${build.temp.file.name}" ... />
<move file="${build.temp.file.name}" tofile="${Feature.dir}\build.xml" />

Resources