1

I have a file with these contents:

<People>
    <Person>
       <Name>Joe Blogs</Name>
       <Address>55 Oxford St</Address>
       ...lots of other properties
    </Person>
    <Person>
       <Name>Jane Pearson</Name>
       <Address>100 Samson St</Address>
       ...lots of other properties
    </Person>
</People>

The only tools I can use are: awk, sed, grep, pcre_grep

I would like to extract the content of each "Person" tag, remove the "Name" line, and calculate the md5 of the block.

So far I've tried:

awk '/<Person>/,/<\/Person>/{print $0}' input.xml | md5sum

However that only returns a single md5. Not one for each block.

  • Is the formatting of the file fixed? Or can the whitespace vary? – choroba Feb 13 '15 at 17:04
  • What do you actually need? To print the blocks or to get a separate md5sum for them? The title and tags of your question suggest the former but it looks like the only problem is the md5sum which has nothing to do with the method you use to print the blocks. Also, can you use perl? What system is this running on? – terdon Feb 13 '15 at 17:09
  • Hi guys, the formatting is fixed, otherwise I wouldn't use sed/awk. Unfortunately the vintage of the linux distro I'm using doesn't have nice xml parsers. Even xmllint is old (pre --xpath). – Fidel Feb 13 '15 at 17:11
  • In essence I would like to see if there are duplicate blocks (without considering the <name> line) – Fidel Feb 13 '15 at 17:12
  • Unfortunately no perl – Fidel Feb 13 '15 at 17:13
3

Try the following awk-script:

awk '
/<Person>/,/<\/Person>/{
    if (! /<Name>/)
        a=a s $0
    s="\n"
    }
/<\/Person>/{
    system("echo \""a"\" |md5sum - ")
    a=s=""
    }' input.xml

Explanation:

  • Collect all lines between tags Person into a variable
  • When meet closing tag /Person call system command than empty a variable
1

using sed as follows

 sed -n  '/^ *<Person> *$/,/^ *<\/Person> *$/{/<Name>/{d};p}' file|md5sum

target all lines in *<Person> *$/,/^ *<\/Person> *.

/<Name>/ check to see if the range has the tag "Name" and then delete this line. Afterwards print the lines ranges and pipe to md5sum

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.