Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100755 123 lines (86 sloc) 2.672 kB
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
1 #! /usr/bin/perl
2
71a18ff @kartiksubbarao Added -c option to do case-insensitive comparisons on the key attribute.
kartiksubbarao authored
3 # $Id: ldifsort.pl,v 1.6 2004/09/30 20:13:59 subbarao Exp $
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
4
5 =head1 NAME
6
7 ldifsort.pl - Sorts an LDIF file by the specified key attribute. The sorted
8 version is written to standard output.
9
10 =head1 DESCRIPTION
11
12 Sorts an LDIF file by the specified key attribute.
13
14 =head1 SYNOPSIS
15
71a18ff @kartiksubbarao Added -c option to do case-insensitive comparisons on the key attribute.
kartiksubbarao authored
16 ldifsort.pl B<-k keyattr> [B<-andc>] file.ldif
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
17
18 =over 4
19
20 =item B<-k>
21
22 Specifies the key attribute for making sort comparisons. If 'dn' is
23 specified, sorting is done by the full DN string, which can be composed of
24 different attributes for different entries.
25
49c7a41 @kartiksubbarao Added option to sort attributes within each entry.
kartiksubbarao authored
26 =item B<-a>
27
28 Specifies that attributes within a given entry should also be sorted. This
29 has the side effect of removing all comments and line continuations in the
30 LDIF file.
31
1cba309 @gbarr Add ldifsort.pl from Kartik Subbarao
gbarr authored
32 =item B<-n>
33
34 Specifies numeric comparisons on the key attribute. Otherwise string
35 comparisons are done.
36
37 =item B<-d>
38
39 Specifies that the key attribute is a DN. Comparisons are done on a
40 DN-normalized version of attribute values. This is the default
41 behavior if 'dn' is passed as the argument to B<-k>.
42
71a18ff @kartiksubbarao Added -c option to do case-insensitive comparisons on the key attribute.
kartiksubbarao authored
43 =item B<-c>
44
45 Specifies case-insensitive comparisons on the key attribute.
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 }
71a18ff @kartiksubbarao Added -c option to do case-insensitive comparisons on the key attribute.
kartiksubbarao authored
87 $value = lc($value) if $args{c};
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 {
96 my $cadn = ($canonicaldns{$a->[0]} ||= canonical_dn($a->[0]));
97 my $cbdn = ($canonicaldns{$b->[0]} ||= canonical_dn($b->[0]));
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.