[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: Sorting the LDAPSEARCH output



Antonin Novak wrote:

> I am looking to present the output from LDAPSEARCH ...
> Does anyone know if it is possible to sort the data ...

It's certainly possible for an LDAP client to sort the results of a search,
after they are received.  For maximum efficiency, use the LDAP Client SDK.
A less efficient but simpler way is to pipe the output from `ldapsearch` to
a program that sorts it; for example, the enclosed Perl script.

#!/usr/local/bin/perl

use Mozilla::LDAP::LDIF 0.07 qw(get_DN sort_attributes);
# ftp://ftp.mozilla.org/pub/directory/perldap/

sub reverseDN {
    my ($dn) = @_;
    return "" if not defined $dn;
    my @rdns = split /,/, $dn; # bug: doesn't support semicolon separator
    use integer;
    my $i;
    for ($i = $[; $i < $#rdns; ) {
        # Rejoin RDNs containing \, or a comma inside a quoted string.
        if ($rdns[$i] =~ /(\"([^\"]|\\")*|\\)$/) {
            splice @rdns, $i-$[, 2, ($rdns[$i] . ',' . $rdns[$i+1]);
        } else {
            ++$i;
        }
    }
    foreach my $rdn (@rdns) { # ignore whitespace preceding each RDN
        $rdn =~ s/^\s*//;
    }
    return join ',', (reverse @rdns);
}

sub byDN {
    # The induced ordering is top-down, depth-first in the DIT.
    my $dnA = lc (reverseDN (get_DN ($a)));
    my $dnB = lc (reverseDN (get_DN ($b)));
    $dnA cmp $dnB;
}

$optEntries = 1;
$optAttrs   = 1;
if (@ARGV) {
    $optEntries = $optAttrs = 0;
    foreach my $arg (@ARGV) {
        if      ("entries"    eq lc $arg) { $optEntries = 1;
        } elsif ("attributes" eq lc $arg) { $optAttrs = 1;
        }
    }
}

@entries = get {new Mozilla::LDAP::LDIF} (undef);
if ($optEntries) { @entries = sort byDN @entries; }
if ($optAttrs) {
    foreach my $entry (@entries) {
        ($entry) = sort_attributes ($entry);
    }
}
put {new Mozilla::LDAP::LDIF (*STDOUT, [encode=>'^ |[^ -\xFD]'])} (@entries);