0

I have a big xhtml file with lots of junk text that I don't need. I only need whatever text that lies between two specific strings that occur many times within that file, e.g.

<html>
<xyz> unneeded text </xyz>
<mytag> important text1 </mytag>
<xyz> unneeded text </xyz>
<xyz> unneeded text </xyz>
<mytag> important text2 </mytag>
<mytag> important text3 </mytag>
<xyz> unneeded text </xyz>
</html>

My output should be:

important text1
important text2
important text3

I need to do that using Bash script.

Thanks for your help

1
  • Please note that <xyz> and </xyz> are not fixed strings. There are a lot of different unneeded tags. Commented Apr 25, 2016 at 8:47

3 Answers 3

2

Using regex on Xml format is risky, particularly with line based text processing tool grep. You cannot make sure that the result is always correct.

If your input was valid xml format, I would go with xml way: xpath expression.

With tool xmlstarlet, you can do:

xmlstarlet sel -t -v "//mytag/text()" file.xml

It gives the desired output.

You can also do it with xmllint, however, you need do some further filtering on the output.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Kent, but the problem is that it's an XHTML file, so it's not well formatted at all, will xmllint be able to handle that?
@SoCRaT Extensible Hypertext Markup Language (XHTML) is part of the family of XML markup languages
0

Using an XML parser would be the best way to go.

Solution using grep with PCRE:

grep -Po '^<mytag>\s*\K.*?(?=\s*</mytag>$)'

Example:

$ cat file.xml                                    
<html>
<xyz> unneeded text </xyz>
<mytag> important text1 </mytag>
<xyz> unneeded text </xyz>
<xyz> unneeded text </xyz>
<mytag> important text2 </mytag>
<mytag> important text3 </mytag>
<xyz> unneeded text </xyz>
</html>

$ grep -Po '^<mytag>\s*\K.*?(?=\s*</mytag>$)' file.xml
important text1
important text2
important text3

1 Comment

Thanks a lot. I will test and get back to you.
0

Using XML parser is a better approach, there are also command line tools for xml parsing in Linux, eg: xmllint but you can do it using grep like this:

$ cat data1 
<html>
<xyz> unneeded text </xyz>
<mytag> important text1 </mytag>
<xyz> unneeded text </xyz>
<xyz> unneeded text </xyz>
<mytag> important text2 </mytag>
<mytag> important text3 </mytag>
<xyz> unneeded text </xyz>
</html>
$ grep -oP '(?<=<mytag>).*(?=</mytag>)' data1
 important text1 
 important text2 
 important text3  
$

(?<=<mytag>).*(?=</mytag>) this extracts text using positive lookahead and lookbehind assertions

1 Comment

Thanks a lot. I will test and get back to you

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.