tags:

views:

257

answers:

4

Hi,

I use ldapsearch to get some users from my LDAP-Server. The command replies something like this:

uid: name.surname
homeDirectory: /home/name
sambaSID: S-1-4-32-224545876-87201423761-4821562975-6853
sambaHomeDrive: G:
description: poI
description: pPI
sn: naut
givenName: givenName: peter
mail: [email protected]

Now I want to assign every string after ":" to a variable (the two descriptions maybe to a array? By sambaSID I just need the last block (6853 in this case [could be longer or shorter]).

Any help would be really appreciated. Here my try with mktmp, sed, grep and many ugly if statements. I have no other idea... http://dpaste.com/97693/

A: 

My contribution which considers multiple keys (like description) and appends the corresponding value (separated by line breaks).

You can use keys as ${keys[@]} in your ldapsearch command instead of $OUTPUT.

I would rather use associative arrays, but they where introduced not until bash 4.0. So I am using to arrays for keys and values and need a function to check if a key exists.

...

keys=(uid homeDirectory sambaSID sambaHomeDrive description sn givenName mail)
declare -a values
i=0

...

index () {
    for ((x=0; x < ${#keys[@]}; x++)); do
        if [ "$1" == "${keys[$x]}" ]; then
            echo $x; return
        fi
    done
    echo -1
}

exec 5<> $LDIF
while read <&5 LINE
do
    key="${LINE%%:*}"
    value="${LINE#$key: }"
    x=`index $key`
    [ "$x" == -1 ] && x=$((i++)) || v="${values[$x]}"
    [ "$key" == "sambaSID" ] && value="${value##*-}"
    values[$x]="${v:+$v
}$value"
done

for ((x=0; x < ${#keys[@]}; x++)); do
    echo "${keys[$x]}: ${values[$x]}"
done

echo "Mail is ${values[`index 'mail'`]}."
andre-r
A: 

Thanks for all your help. :)

The solution from andre-r fits it best. But has one problem. Here's the output from the script:

script.sh: line 29: [: ==: unary operator expected uid: uid=name.surname,ou=Users,dc=smb,dc=chname.surname homeDirectory: sambaSID: 8426 sambaHomeDrive: G: description: p9o sn: martheus givenName: name mail: [email protected]

So the uid isn't right and sambaHomeDrive isn't resolved. Can't fix it. :/

But really thanks for all your help!

fwa
Sorry, my bad. I updated the answer. It is always a good idea to enclose variables in "".
andre-r
didnt work. but really many thank for your help :)uid is uid=name.nname,ou=Users,dc=aksa,dc=chname.nname.Mail is [email protected] is .
Peter Parker
Can you paste this code, please, which didn't work?
andre-r
i used your code 1:1 just with my lines above. can't acces the code atm. sorry.but i solved my problem with a edited version from dz's code.thank you
Peter Parker
A: 

If you don't really care about duplicate keys, and assuming everything to the left of the first ":" is alphanumeric and nothing to the right contains a single quote, the following will do:

while read line; do
  eval $(echo "$line" | sed 's/^\([^:]\+\):[ ]\+\(.*\)/\1='"'"'\2'"'/")
done

echo "uid is $uid, home directory is $homeDirectory."

If you really need to preserve duplicate keys, it wouldn't be too hard to modify this to support it. Of course, "eval" can be dangerous, as it has already been pointed out, but if the assumptions above hold (no single quotes on the right of ":"), this use is safe.

Idelic
+1  A: 

It's so much simpler than that if you have bash, which you probably do.


#!/bin/bash
while read line ; do
        n="${line%%:*}"
        v="${line#*: }"
        eval $n=\"$v\"
done
sambaSID=${sambaSID/*-/}

$ ldapsearch | this_script.sh

At this point all requirements are met and you have local variables named after each ldiff attribute. This doesn't make it a good idea.

Sorpigal