1

I retrieve from LDAP all kerberos users (but only some of their variables e.g. kerberosid,location, mail, name, surname,... ) into a flat file (delimiter is pipeline).

I tried to use LDAP syntax from LDAPSEARCH into table format but I am getting mixed values I mean (I can see e.g. the same name in next line, but next line in the file starts with second LDAP record, etc.) Performance is important.

I would prefer to have even empty string in position where value is missing. I am not sure if this is not happening because in some previous records whole index (variable e.g. mail) is missing and from this position all is shifted...

Code block from the link :

$ ldapsearch -x -D "cn=something" | awk -v OFS=',' '{split($0,a,": ")} /^mail:/{mail=a[2]} /^uidNumber:/{uidNumber=a[2]} /^uid:/{uid=a[2]} /^cn/{cn=a[2]; print uid, uidNumber,cn , mail}' > ldap_dump.csv

Ldap search output:

dn: xxxxx 
objectClass: top 
mail: 11111
uidNumber: 222 222 
uid: 333, 3333 
cn: 44444 
somethingnext: 5555

dn: new records 
objectClass: top 
mail: aaaaa 
uidNumber: bbbbb 
uid: cccc, cccc 
cn: ddddd 
somethingnext: eeeee

each line is on new line and between records is empty new line

Needed output in a file should be : 
11111|222 222|333, 3333|44444
aaaaa|bbbbb|cccc, cccc|ddddd
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Matt
  • 11
  • 4
  • What is the output of `ldapsearch -x -D "cn=something"`? And how would you like it to be presented? – Inian Dec 05 '18 at 11:52

1 Answers1

1

Use the following awk:

awk 'BEGIN{RS=""; OFS="|"}
     { mail = cn = uidNumber = uid = ""
       for(i=1;i<=NF;++i) {
          if ($i ~ /^mail:/) { mail=substr($i,7) }
          else if ($i ~ /^uidNumber:/) { uidNumber=substr($i,12) }
          else if ($i ~ /^uid:/      ) { uid=substr($i,6) }
          else if ($i ~ /^cn:/       ) { cn=substr($i,5) }
       }
       print mail,uidNumber,uid,cn
     }'

A corrected version of your original version is:

awk 'BEGIN{FS=": *"; OFS="|"}
     (NF==0) { print uid,uidNumber,cn,mail }
     (NF==0) { mail = uidNumber = uid = cn = ""; next }
     {split($0,a,": ")}
     /^mail:/{mail=a[2]}
     /^uidNumber:/{uidNumber=a[2]}
     /^uid:/{uid=a[2]}
     /^cn/{cn=a[2]}
     END{ print uid,uidNumber,cn,mail }'
kvantour
  • 25,269
  • 4
  • 47
  • 72
  • actually values have various length. I am using split function to put them into array. I took idea form the example, so far I've got here but it doesn't work: $ ldapsearch -x -D "cn=something" | awk -v OFS=',' '{split($0,a,": ")} { mail=""; if(a[1] ~ /^mail:/) mail=a[2];} /^uidNumber:/{uidNumber=a[2]} /^uid:/{uid=a[2]} /^cn/{cn=a[2]; print uid, uidNumber,cn , mail}' > ldap_dump.csv What am I doing wrong ? I am beginner with this... – Matt Dec 05 '18 at 15:58
  • I found that the mail is not always. It means that first record has mail: 11111 but second doesn't even "mail :" – Matt Dec 05 '18 at 16:03
  • @Matt the above should work, as the length of the strings `mail: ` and `uid: ` are always the same. – kvantour Dec 05 '18 at 16:48
  • @Matt your problem is that you do not reset the variables to an empty string. you should check if you have zero fields for the reset. I.e. your first awk line should read `(NF==0){mail=uidNumber=uid=cn=""}` – kvantour Dec 05 '18 at 16:50
  • is it possible to transform it somehow for my example with the split command ? – Matt Dec 05 '18 at 17:08