Search code examples
bashldap

how to group ldap search results by attributes and not by cn. using bash


I have this scriplet that pulls data from a ldap. it lists the attributes with the cn and the value. but it goes through all the attributes of a cn and then moves to the next.

for node  in "${HOSTS[@]}"; do
        LDAP_URI="ldaps://${node}:${LDAP_PORT}"
        while IFS=: read -r key val; do
        [[ $key = cn ]] && { cn=${val# }; continue; }
        if [[ $val =~ ^\ -?[0-9]+(\.[0-9]+)?$ ]]; then
            attr=$(sed 's/-/_/g' <<< "$key")l"
            printf '%s, cn="%s %s\n"' "$attr" "$cn" "$val"
        fi
        done < <( ${LDAPSEARCH} -LLL -H "${LDAP_URI}" -x -D "${BINDDN}" -w "${LDAP_PASSWD}" -b "cn=monitor")
    done;

the code above produces output like this:

"connections, cn="1636  -632
"bytessent, cn="1636  492842558
"connections, cn="1389  698
"bytessent, cn="1389  389256181

but I do not want to group by cn but group by attribute like this:

"bytessent, cn="1389  389261940
"bytessent, cn="1636  711130488
"connections, cn="1389  700
"connections, cn="1636  -632

what would be the best way to achieve this?


Solution

  • One idea would be to pipe the entire output to sort.

    I don't have all the bits-n-pieces to get OP's working so I'll simulate with an echo:

    echo '"connections, cn="1636  -632
    "bytessent, cn="1636  492842558
    "connections, cn="1389  698
    "bytessent, cn="1389  389256181' | sort
    

    This generates:

    "bytessent, cn="1389  389256181
    "bytessent, cn="1636  492842558
    "connections, cn="1389  698
    "connections, cn="1636  -632
    

    Adding to OP's code (see last line):

    for node  in "${HOSTS[@]}"; do
        ... snip ...
    done | sort                            # send all output to sort
    

    I'm guessing OP really wants to end each line with a " so that it looks like:

    "bytessent, cn="1389  389256181"
    "bytessent, cn="1636  492842558"
    "connections, cn="1389  698"
    "connections, cn="1636  -632"
    

    To accomplish this just need to tweak the printf format to switch the last " and the \n:

    printf '%s, cn="%s %s\n"' "$attr" "$cn" "$val"         # before
    printf '%s, cn="%s %s"\n' "$attr" "$cn" "$val"         # after