Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a large file part of which is like below:

<DataGroup xsi:type="ReportDataGroup">
<SmartReportTemplate DescriptionContentType="text/plain"
<Name ns1:translate="yes">Agent Summary</Name>
<Defaults type="defaults">
<Title ns1:translate="yes">Agent Summary Report</Title>
<Description ns1:translate="yes"></Description>

Now I need to check for the patterns .*ns1:translate="yes">(.*)</.* and when found I need to add string from the array below this line. Along with the string from the array I need to add the tags <Name xml:lang="ja"> and </Name> around the string obt from the array if the line above has </Name> and need to add <Title xml:lang="ja"> and </Title> tags if the pattern matched line has </Title>

The final output should look like:

<DataGroup xsi:type="ReportDataGroup">
<SmartReportTemplate DescriptionContentType="text/plain"
<Name ns1:translate="yes">EM - perc</Name>
<Name xml:lang="ja">\u886815wEM - perce ~~~~~~~~~ ~~~~~~~~~ ~~\u5834</Name>
<Defaults type="defaults">
<Title ns1:translate="yes">AG - Rep</Title>
<Title xml:lang="ja">\u886815wAG - Rep ~~~~~~~~~ ~~~~~~~~~ ~~\u5834</Title>
<Description ns1:translate="yes"></Description>

where the strings "\u886815wEM - perce ~~~~~~~~~ ~~~~~~~~~ ~~\u5834" etc ... are there in an array.

Any idea how to script this? I tried with sed inside a while loop that reads file line by line but it takes a very long time. I tried with awk but I am not able to access the special character array inside awk.

share|improve this question
See… before anyone gets angry with you for wanting to modify XML through regular expressions :-) – Daniel Andersson Jun 15 '12 at 8:58
How are array contents mapped to replacements? Sequentially (i.e. one array item per match, counting upwards?). – kopischke Jun 17 '12 at 11:01
@DanielAndersson: humourous value of the linked answer apart, there are situations where a regex can be enough – especially as regular expressions are perfectly able to match (albeit not parse) well-formed XML. It’s all the difference between a robust architecture for this kind of task and a quick hack. As long as you are aware that a hack is just that (at best brittle and at worst erratic), it might be the easier solution to pull a a quick one, compared to, say, XSLT or custom XML processing in a script. – kopischke Jun 17 '12 at 11:07

If a partial solution in vim is acceptable:

:%s/\(.*\(Name\|Title\).*ns1:translate="yes">.*<\/.*\)/<\2 xml:lang="ja">\\u886815wEM - perce \~\~\~\~\~\~\~\~\~ \~\~\~\~\~\~\~\~\~ \~\~\\u5834<\/\2>\r\1/g

escaping \ by \/ and ~ by \~.

\(Name\|Title\) allows matching two patterns and recalling them with \2 here.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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