0

I have a lot of files that match a grep 'xmltag' and 'subtag'.

random xml
needed_text
random xml
<xmltag>
<subtag>content</subtag>
</xmltag>

I want to search for files that match another text 'needed_text'.

The output should contain 'content' at the very least, but complete lines would also be acceptable:

<xmltag>
     <subtag>content</subtag>
</xmltag>

xmltag and subtag maybe on same or on different lines

grep -rl "needed_text" * 

gives a list of file names i need as input for the second part, but how do i feed that to another grep (or other command) and how do i make sure it finds only the combination of xmltag and subtag

1 Answer 1

1

To pass the list of files to another command, you'd use xargs. For it to be reliable, you need the -0 option as supported by most modern implementations, and the list of file paths must be passed NUL-delimited (using the -Z option with GNU grep or compatible).

grep -rlZ "needed_text" . |
  xargs -r0 pcregrep -Mo '(?s)<xmltag>.*?</xmltag>'

(assuming there are no nested <xmltag>s and the <xmltag>s won't occur in CDATA, and the usual caveats associated with parsing XML with regexps).

If the files are proper XML files, you can use XML aware tools like xmllint, xpath, xmlstarlet instead of pcregrep to extract the tags you want.

grep -rlZ "needed_text" . |
  xargs -r0 xpath -e //xmltag

Or for only the xmltags that have at least one subtag:

grep -rlZ "needed_text" . |
  xargs -r0 xpath -e //xmltag/subtag/..

(here using the xpath shipped with the XML::XPath perl module).

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .