0

I have a very long XML file that has some repeating sections. I want to find the line number which is the closest occurrence of string B on string A. Say I have many instances of:

<section>
  ...
  <entry>
    <key>key-im-looking-for</key>
    ...
  </entry>
  ...
  <type>org.apache.whatever.package</type>
  ...
</section>

I want to find the line number that contains

key-im-looking-for

which is nearest to (or contained in same section) <type>org.apache.whatever.package</type> as the search term, using either grep, awk or sed.

  • The closest pattern or the nearest line? – DarkHeart Dec 17 '17 at 12:47
  • 1
    can you make up a small example input and the expected output to make it unambiguous? Does it matter which order those strings appear? – ilkkachu Dec 17 '17 at 12:49
  • Hmm I wonder what the smartest way to do this would be. Do you have multiple copies of both the key and the type? If there's only one of either, then it's easy to just target that. If you have multiples, and you want to find all pairs in the same section, then it would probably be a job for an XML parser. Perl and Python have rather easy to use libraries for that. But I'm not sure if they think in terms of line numbers then... – ilkkachu Dec 17 '17 at 13:08
  • "Nearest" means only before the <type>org.apache.whatever.package</type> line, or around this line, that is - before and after? If we have needed key, three lines before the apache.whatever and also, two lines after it, which we should pick? – MiniMax Dec 17 '17 at 13:11
  • I already did similar task, you can customize it for your needs Finding a string with AWK before or after an iteration of a repeated sequence. – MiniMax Dec 17 '17 at 13:18
2

First of all, I find it a bit strange to look for a line number in XML. XML is a tree structure, where whitespaces are irrelevant, and therefore line numbers should also be irrelevant. This makes me wonder if this is an XY Problem.

Second of all, and if I ignore the matter of the line number, it's generally best to use a proper XML parser, or something that can do XPATH queries. In terms of XML, your question is close to "what's the key of the node whose type is X". Which is a reasonable, well-defined question to ask, when working with XML.

That being said, if the "nearest" <key> always comes before the <type>, then you can consider this algorithm in awk:

  • If the line matches <key>key-im-looking-for<, record the line number
  • If the line matches <type>org.apache.whatever.package<, stop processing
  • At the end, print the recorded line number

Something like this:

awk '/<key>key-im-looking-for</ { line=NR }
     /<type>org.apache.whatever.package</ { exit }
     END { print line }' input.xml
1

This should be possible using the following commands:

cat -n sample.xml | grep key-im-looking-for
# or
grep -n key-im-looking-for sample.xml
  • Or just grep -n, it's even standard, while cat -n isn't. – ilkkachu Dec 17 '17 at 13:50
  • standard: what does that mean? – George Udosen Dec 17 '17 at 13:58
  • well, lots of things, if you look at a dictionary... But what I meant is that grep -n is a feature specified by POSIX, so it's likely to be commonly supported even in systems that don't have tools that are as featureful as the the GNU utils – ilkkachu Dec 17 '17 at 14:04
  • Ok I thought you meant it was coding standard! – George Udosen Dec 17 '17 at 14:05

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.