Praise teh sed

Posted on Sunday, 5th August, 2007 in Gentoo, Life

Since my talk with Robin on Thursday regarding the autogenerated userinfo.xml, I finally found some time today to get all the info’s I need out of userinfo.xml.

Since I don’t really want to manually enter all those mail addresses from userinfo into LDAP manually, I figured sed might be my best friend. *BUT* sed ain’t easy .. But thanks to Fabian and Gilles, I learned something new about sed today ..

Basically I searched for a way to transform userinfo.xml into a datafile for ldapedit.

As most of you know, userinfo.xml would look like this:

  <user username="phreak">
    <realname fullname="Christian Heim">
      <firstname>Christian</firstname>
      <familyname>Heim</familyname>
    </realname>
    <pgpkey>0x9A9F68E6</pgpkey>
    <email role="gentoo">phreak@gentoo.org</email>
    <joined>06 August 2005</joined>
    <birthday></birthday>
    <roles>vserver, openvz, kernel</roles>
    <location longitude="13.032" latitude="54.251">Germany, Stralsund</location>
  </user>

So the first step would be to simply use egrep on userinfo.xml to filter only the things I needed ..

celsius roll-call [0] $ egrep "(username=|<email |</user>)" \
userinfo.xml

That looks more like a processable list to me. Now I only needed to convert the into dn, the into mail and be done with it.

This is what I applied on top of the above filter:

celsius roll-call [0] $ egrep "(username=|<email |</user>)" \
userinfo.xml | \
 sed -e "s,.*<user username=\",dn: uid=," \
     -e "s,\">$,\,ou=devs\,dc=gentoo\,dc=org\nadd: mail," \
     -e 's,.*<email role="\\(gentoo\\|primary\\)">,mail: ,' \
     -e "s,</email>,," -e "s,  </user>,,"

And that’s it, I just need to check the dn’s for all the users, and when I’m done with that, finito!


2 Responses to “Praise teh sed”


  1. Hope this isn’t a repeat; my first attempt to post failed.

    It shouldn’t be necessary to combine grep and sed this way. sed can do the grep part, which will save you a pipe and some time and effort if you do this command over a large file or group of files.
    I might have this somewhat wrong, but you could put those commands in an external file called userinfo.sed, and invoke it with the -f flag; something like:

    userinfo.sed:
    ,(username=|),{
    s/.*$/,ou=devs,dc=gentoo,dc=org\nadd: mail/
    s/.*/mail: /
    ,,d
    , ,d
    }p

    sed -nf userinfo.sed userinfo.xml

    On the other hand, sed is not usually the best choice for modifying xml. Far from it, in fact. XSLT was built for mangling xml and does it much more consistently and reliably than sed ever will. I’m not prepared to give an example of doing this transformation with XSLT at the moment, but I guarantee it’s the right way to go here.


  2. Mmkay, try this xslt:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" encoding="utf-8"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/user">dn: uid=<xsl:value-of select="@username"/>,ou=devs,dc=gentoo,dc=org
    add: mail
    <xsl:apply-templates select="email[@role='gentoo']"/>
    <xsl:apply-templates select="email[@role='primary']"/>
    </xsl:template>
    <xsl:template match="email">
    mail: <xsl:value-of select="."/>
    </xsl:template>
    </xsl:stylesheet>

Leave a Reply