Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100755 123 lines (87 sloc) 2.751 kB
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
1 #! /usr/bin/perl
f96bdda @kartiksubbarao Treat comparison case-insensitively when the dn is the key attribute.…
kartiksubbarao authored
2 # $Id: ldifsort.pl,v 1.9 2005/04/03 20:20:24 subbarao Exp $
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
3
4 =head1 NAME
5
6 ldifsort.pl - Sorts an LDIF file by the specified key attribute. The sorted
7 version is written to standard output.
8
9 =head1 DESCRIPTION
10
11 Sorts an LDIF file by the specified key attribute.
12
13 =head1 SYNOPSIS
14
71a18ff @kartiksubbarao Added -c option to do case-insensitive comparisons on the key attribute.
kartiksubbarao authored
15 ldifsort.pl B<-k keyattr> [B<-andc>] file.ldif
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
16
17 =over 4
18
19 =item B<-k>
20
21 Specifies the key attribute for making sort comparisons. If 'dn' is
22 specified, sorting is done by the full DN string, which can be composed of
23 different attributes for different entries.
24
49c7a41 @kartiksubbarao Added option to sort attributes within each entry.
kartiksubbarao authored
25 =item B<-a>
26
27 Specifies that attributes within a given entry should also be sorted. This
28 has the side effect of removing all comments and line continuations in the
29 LDIF file.
30
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
31 =item B<-n>
32
33 Specifies numeric comparisons on the key attribute. Otherwise string
34 comparisons are done.
35
36 =item B<-d>
37
38 Specifies that the key attribute is a DN. Comparisons are done on a
39 DN-normalized version of attribute values. This is the default
40 behavior if 'dn' is passed as the argument to B<-k>.
41
71a18ff @kartiksubbarao Added -c option to do case-insensitive comparisons on the key attribute.
kartiksubbarao authored
42 =item B<-c>
43
f96bdda @kartiksubbarao Treat comparison case-insensitively when the dn is the key attribute.…
kartiksubbarao authored
44 Specifies case-insensitive comparisons on the key attribute. This is the
45 default behavior if 'dn' is passed as the argument to B<-k>.
71a18ff @kartiksubbarao Added -c option to do case-insensitive comparisons on the key attribute.
kartiksubbarao authored
46
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
47 =back
48
49
50 =head1 AUTHOR
51
52 Kartik Subbarao E<lt>subbarao@computer.orgE<gt>
53
54 =cut
55
56
57 use Net::LDAP::Util qw(canonical_dn);
58 use MIME::Base64;
59 use Getopt::Std;
60
61 use strict;
62
63 my %args;
71a18ff @kartiksubbarao Added -c option to do case-insensitive comparisons on the key attribute.
kartiksubbarao authored
64 getopts("k:andc", \%args);
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
65
66 my $keyattr = $args{k};
49c7a41 @kartiksubbarao Added option to sort attributes within each entry.
kartiksubbarao authored
67 my $sortattrs = $args{a};
71a18ff @kartiksubbarao Added -c option to do case-insensitive comparisons on the key attribute.
kartiksubbarao authored
68 my $ciscmp = $args{c};
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
69 my $ldiffile = $ARGV[0];
70
71a18ff @kartiksubbarao Added -c option to do case-insensitive comparisons on the key attribute.
kartiksubbarao authored
71 die "usage: $0 -k keyattr [-n] [-d] [-c] ldiffile\n"
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
72 unless $keyattr && $ldiffile;
73
74 $/ = "";
75
76 open(LDIFH, $ldiffile) || die "$ldiffile: $!\n";
77
78 my $pos = 0;
79 my @valuepos;
80 while (<LDIFH>) {
81 my $value;
82 1 while s/^($keyattr:.*)?\n /$1/im; # Handle line continuations
83 if (/^$keyattr(::?) (.*)$/im) {
84 $value = $2;
85 $value = decode_base64($value) if $1 eq '::';
86 }
f96bdda @kartiksubbarao Treat comparison case-insensitively when the dn is the key attribute.…
kartiksubbarao authored
87 $value = lc($value) if $ciscmp;
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
88 push @valuepos, [ $value, $pos ];
89 $pos = tell;
90 }
91
92 sub cmpattr { $a->[0] cmp $b->[0] }
93 sub cmpattrnum { $a->[0] <=> $b->[0] }
94 my %canonicaldns;
95 sub cmpdn {
f96bdda @kartiksubbarao Treat comparison case-insensitively when the dn is the key attribute.…
kartiksubbarao authored
96 my $cadn = ($canonicaldns{$a->[0]} ||= lc(canonical_dn($a->[0])));
97 my $cbdn = ($canonicaldns{$b->[0]} ||= lc(canonical_dn($b->[0])));
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
98 $cadn cmp $cbdn;
99 }
100
101 my $cmpfunc;
102 if ($args{d} || lc($keyattr) eq 'dn') { $cmpfunc = \&cmpdn }
103 elsif ($args{n}) { $cmpfunc = \&cmpattrnum }
104 else { $cmpfunc = \&cmpattr; }
105
106 my @sorted;
107 @sorted = sort $cmpfunc @valuepos;
108
109 foreach my $valuepos (@sorted) {
110 seek(LDIFH, $valuepos->[1], 0);
111 my $entry = <LDIFH>;
49c7a41 @kartiksubbarao Added option to sort attributes within each entry.
kartiksubbarao authored
112 if ($sortattrs) {
113 $entry =~ s/\n //mg; # collapse line continuations
114 my @lines = grep(!/^#/, split(/\n/, $entry));
115 my $dn = shift(@lines);
116 print "$dn\n", join("\n", sort @lines), "\n\n";
117 }
118 else {
119 print $entry;
120 print "\n" if $entry !~ /\n\n$/;
121 }
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
122 }
Something went wrong with that request. Please try again.