Forum Discussion

Ping_Xiong_1567's avatar
Ping_Xiong_1567
Historic F5 Account
Apr 18, 2012

convert ldapsearch result into external datagroup format

Hi Guys,

 

 

I come cross a requirement to convert a txt file into external datagroup format in background.

 

 

The source file is the result from ldapsearch, something like this:

 

 

dn:

 

r1+sn=test,ou=people,dc=my-domain,dc=com

 

cn: client1

 

mailHost: mailserver1

 

 

dn:

 

r2+sn=test,ou=people,dc=my-domain,dc=com

 

cn: client2

 

mailHost: mailserver2

 

 

I need a scripts to convert it into external datagroup format like this:

 

 

"client1" := "mailserver1",

 

 

“client2" := "mailserver2",

 

 

Then use datagroup as a reference to distribution traffic to mailservers.

 

 

If anyone has similar scripts on hand, please share me.

 

Thanks a lot!!

 

3 Replies

  • Hamish's avatar
    Hamish
    Icon for Cirrocumulus rankCirrocumulus
    Give me a couple of hours. I have some perl scripts that do stuff like this. I will dig them out.

     

     

    H

     

  • Hi Guys,

    I come cross a requirement to convert a txt file into external datagroup format in background.

    The source file is the result from ldapsearch, something like this:

    dn: cn=client1+givenName=client1+m...erve

    r1+sn=test,ou=people,dc=my-domain,dc=com

    cn: client1

    mailHost: mailserver1

    dn: cn=client2+givenName=client2+m...erve

    r2+sn=test,ou=people,dc=my-domain,dc=com

    cn: client2

    mailHost: mailserver2

    I need a scripts to convert it into external datagroup format like this:

    "client1" := "mailserver1",

    "client2" := "mailserver2",

    Then use datagroup as a reference to distribution traffic to mailservers.

    If anyone has similar scripts on hand, please share me.

    Thanks a lot!!

    Here’s a quick and dirty one liner:

    cat ldif.txt |egrep "^(cn:|mailHost:)" |cut -d: -f 2- |sed -e 's/^ //' -e 'N;s/\n /|/' |awk -F\| '{print "\""$1"\" := \""$2"\","}'

    Sample ldif file

    $ cat ldif.txt

    dn: cn=client1+givenName=client1+mail=c...=mailserve

    r1+sn=test,ou=people,dc=my-domain,dc=com

    cn: client1

    mailHost: mailserver1

    dn: cn=client2+givenName=client2+mail=c...=mailserve

    r2+sn=test,ou=people,dc=my-domain,dc=com

    cn: client2

    mailHost: mailserver2

    dn: cn=client3+givenName=client3+mail=c...=mailserve

    r3+sn=test,ou=people,dc=my-domain,dc=com

    cn: client3:test:with:colons

    mailHost: mailserver3

    Output for the sample file

    $ cat ldif.txt |egrep "^(cn:|mailHost:)" |cut -d: -f 2- |sed -e 's/^ //' -e 'N;s/\n /|/' |awk -F\| '{print "\""$1"\" := \""$2"\","}'

    "client1" := "mailserver1",

    "client2" := "mailserver2",

    "client3:test:with:colons" := "mailserver3",

    Breakdown of the commands:

    cat ldif.txt - write file to standard output

    egrep "^(cn:|mailHost:)" - get lines starting with cn: or mailHost:

    cut -d: -f 2- - split the lines on a delimiter of : and return the second through last fields

    sed -e 's/^ //' -e 'N;s/\n /|/' - remove leading spaces and replace every other new line with a pipe

    awk -F\| '{print "\""$1"\" := \""$2"\","}' - split on the pipe and format the fields with “name” := “value” format

    And here's a cleaner option from John Gruber using Perl:

    
    !/usr/bin/perl
    if($ARGV < 1) {
        print $ARGV."\n";
        print "$0 [ldifffile] [datagroupfile]\n";
        exit(0);
    }
    open(LDIFFFILE, "<".$ARGV[0]) or die "Can't open ".$ARGV[0]."\n";
    open(DATAGROUP, ">".$ARGV[1]) or die "Can't open ".$ARGV[1]."\n";
    while()
    {
      my($line) = $_;
      chomp($line);  
      if ($line =~ /^cn:/) {
          print DATAGROUP "\"".substr($line,index($line,': ')+2)."\" := \"";
      }
      if ($line =~ /^mailHost:/) {
          print DATAGROUP substr($line, index($line,':')+2)."\"\n";
      }
    }
    close(LDIFFFILE);
    close(DATAGROUP);

    Aaron

  • And an even simpler awk example from James Quinby:

     

     

     

    awk 'BEGIN{RS=" \n";FS="\n"};{print $3,$4}' input.txt | awk '{print "\042"$2"\042 := \042"$4"\042,"}'

     

     

    First awk breaks the records by blank-lines (RS) and the fields (FS) by newlines – this prints the last 2 lines of each record side-by-side.

     

    Second awk splits by spaces and prints the correct fields, delimiter and double-quotes.

     

     

    N.B.: The sample input was a space on a blank line between records – you’ll want to adjust the RS in that first awk accordingly if the actual record separator is a true bare linefeed. This could probably be combined into a single awk script.

     

     

     

    Aaron