name=Document1.doc type=Word author=aAuthor name=Document1.doc type=Excel author=bAuthor name=Document1.doc type=Text author=cAuthor name=Document1.doc type=Excel author=dAuthor name=Document1.doc type=Word author=eAuthorMy problem is to sort this file and write to another (first based on the key "type" and then on the key "author") so that the output file looks like :
name=Document1.doc type=Excel author=bAuthor name=Document1.doc type=Excel author=dAuthor name=Document1.doc type=Text author=cAuthor name=Document1.doc type=Word author=aAuthor name=Document1.doc type=Word author=eAuthorWhat I have tried is to write a function which accepts one key name and sort the file based on that key. Again the function will be invoked with the second key. But when I invoked the function with second key, the output happened to be sorted in second key alone(the first level sorting has gone which is obvious). Is there any way with which I can do this in one stretch.?
#$field is the position of the element (sort key) in the #line
open INPUT , $input || die $input.$! ;
while () {
@fields = split(" ",$_) ;
push @{$hash{$fields[$field]}}, $_ ;
$hash_keys{$fields[$field]} = $fields[$field] unless exists $hash_keys{$fields[1]} ;
}
for $element (sort keys %hash_keys) {
open OUTPUT, ">>$output" || $output.$! ;
print OUTPUT @{$hash{$element}} ;
close OUTPUT ;
}
close INPUT ;
Many thanks for your time..
Here's a starting point:
use strict;
use warnings;
my @rows;
push @rows, [split ' '] while ;
print "@$_\n" for sort {$a->[1] cmp $b->[1] or $a->[2] cmp $b->[2]} @rows;
__DATA__
name=Document1.doc type=Word author=aAuthor
name=Document1.doc type=Excel author=bAuthor
name=Document1.doc type=Text author=cAuthor
name=Document1.doc type=Excel author=dAuthor
name=Document1.doc type=Word author=eAuthor
Prints:
name=Document1.doc type=Excel author=bAuthor name=Document1.doc type=Excel author=dAuthor name=Document1.doc type=Text author=cAuthor name=Document1.doc type=Word author=aAuthor name=Document1.doc type=Word author=eAuthor
[0] Perl> @toSort = split "\n", <<'END';
name=Document1.doc type=Word author=aAuthor
name=Document1.doc type=Excel author=bAuthor
name=Document1.doc type=Text author=cAuthor
name=Document1.doc type=Excel author=dAuthor
name=Document1.doc type=Word author=eAuthor
END
;;
Perl> print for map{
$_->[0]
} sort{
$a->[1] cmp $b->[1]
} map{
[ $_, join'', m[type=(\S+)\s+author=(\S+)] ]
} @toSort;;
name=Document1.doc type=Excel author=bAuthor
name=Document1.doc type=Excel author=dAuthor
name=Document1.doc type=Text author=cAuthor
name=Document1.doc type=Word author=aAuthor
name=Document1.doc type=Word author=eAuthor
# Create a keysort function that uses two strings as keys:
use Sort::Key::Maker ss_keysort => qw(string string);
# And then use it.
# The first argument passed is the subroutine
# to extract the keys from the data:
my @sorted_by_type_and_author =
ss_keysort {
/^name=.*? type=(.*?) author=(.*?)$/;
($1, $2)
} @lines;
perlmonks.org content © perlmonks.org and BrowserUk, GrandFather, Mandrake, salva
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03