I have an xml file which looks like below


<entryName>Total Deep</entryName>

<entryName>Total Saurav</entryName>

<entryName>Total Ankur</entryName>

I was trying to search the pattern "Total Deep" and after that i want to comment out the the tag after 3rd or 4th line of the matching pattern in xml file

My code is below

while read -r line do;
LineNum=`grep -n "Total Deep" input.xml | cut -d: -f 1`
TOTAL=`expr $LineNum + 4`
echo $LineNum
echo $TOTAL
done < file.txt

While executing the code i am getting below exception

expr: syntax error

Can anyone tell me what is wrong in this code?

  • Could you please check what the output of grep -n "Deep" Formula.xml | cut -d: -f 1 is? In general, it would be better to parse the XML file using an XML parser, such as xmlstarlet (but I'm a bit confused about what you're wanting XML line numbers for, as the XML format is not line oriented). – Kusalananda Mar 10 at 11:44
  • The output is the line numbers where Deep is present like for eg 39806 and 45608 and i need to use it via shell scripting – DEEP MUKHERJEE Mar 10 at 11:46
  • So, you get multiple values back? Do you recognize that using multiple values in expr at the same time would be a problem? What you have is something like expr 39806 45608 + 9. It would be better to tell us what the XML file is and what values needs to be extracted from it to achieve what you want to do. Using grep is not the right approach to reading an XML file. – Kusalananda Mar 10 at 11:48
  • i have modified my questions and the xml file details has been added in my question. Could you please help me on this? – DEEP MUKHERJEE Mar 10 at 11:57
  • Which line do you want to comment out? You say 3rd or 4th. Do you mean the <job> tag? – Kusalananda Mar 10 at 12:02

Your issue is that grep returns multiple line matching your expression. What you end up executing with expr is something like expr 1 3 4 + 4 (if there are matches on lines 1, 3, and 4). This is where your syntax error comes from.

From comments, it is clear that you want to comment out a particular child node from a particular ReconSummary node. If you had wanted to delete e.g. the job node, I would have suggested using

xmlstarlet ed -d '//ReconSummary[entryName = "Total Deep"]/job' file.xml >newfile.xml

... but commenting out rather than deleting is a bit more tricky.

Similar to an answer to your previous question that I wrote just moments ago, this would be done with an XSL transformation:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:template match="/|node()|@*">
      <xsl:apply-templates select="node()|@*"/>

  <xsl:template match="//ReconSummary[entryName = 'Total Deep']/job">
    <xsl:text disable-output-escaping="yes">&lt;!-- </xsl:text>
    <xsl:copy-of select="."/>
    <xsl:text disable-output-escaping="yes"> --&gt;</xsl:text>


The XPATH query //ReconSummary[entryName = 'Total Deep']/job matches the job child node of the ReconSummary node whose entryName child node has the value Total Deep.

You can change this easily to instead comment out the Tran node. The XPATH query for that would be

//ReconSummary[entryName = 'Total Deep']/Tran`

To match both the job and the Tran node, use

//ReconSummary[entryName = 'Total Deep']/*[name()='job' or name()='Tran']

As in my previous answer, you would apply this XSL transformation to your XML file using either of

xmlstarlet tr transform.xsl file.xml >newfile.xml


xsltproc transform.xsl file.xml >newfile.xml

where you file is file.xml and the transformation is stored in transform.xsl.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.