Can someone help me on perl script for "how to sort flat file on third field & stored sorted output in the output flat file"?

In this example - I have input file with unique key column (third field)& I want sorted output get stored in the output file.
e.g.
Input File ->
1780437|20110705|0000007704000000000000004888|7704|48881|PE|08/12/2008 11:38:54|0|1000.00
1780437|20110705|0000007704000000000000004882|7704|48882|PE|08/12/2008 11:38:54|0|1000.00
1780437|20110705|0000007704000000000000004889|7704|48887|PE|08/11/2008 11:38:54|0|1000.00
1780437|20110705|0000007704000000000000004881|7704|48888|PE|08/12/2008 11:38:54|0|1000.00

Expected Output File ->
1780437|20110705|0000007704000000000000004881|7704|48888|PE|08/12/2008 11:38:54|0|1000.00
1780437|20110705|0000007704000000000000004882|7704|48882|PE|08/12/2008 11:38:54|0|1000.00
1780437|20110705|0000007704000000000000004889|7704|48887|PE|08/11/2008 11:38:54|0|1000.00
1780437|20110705|0000007704000000000000004888|7704|48881|PE|08/12/2008 11:38:54|0|1000.00

Okay - you have a couple ways of doing this:

According to your input the only fields that are different are 2 and 4 (starting with 0)

So you could simply open the input file, sort the input file, then write it to a new file.

Or you could open the input file, create a hash using field 2 as a key and sort it that way before writing to a new file.
This is a sample of simply opening the file, sorting it and printing it to another file:

open(FILE,"$infile");
(@linka = <FILE>);
close(FILE);

open (DATABASE,">$outfile");
@DB=<DATABASE>;

@sorted = sort @linka;
foreach my $i(@sorted) 
	{
	print DATABASE "$i";
	}
close (DATABASE);

I don't have a version using a hash hiding in my repertoire at the moment.

Edited 4 Years Ago by Dandello: n/a

Thanks Dandello for reply. However, it looks like this perl script is sorting input file based on all fields. But, if we want sorting input file based on just third field of the input file, which unique key. Can you please suggest me "how should write script for it"?

Look up how to build a hash using the third field as the key - since that's what you need. Sorry I don't have a good example right now to just show you. Give me a few hours and I'll see what I can find. But a hash is what you need.

Edited 4 Years Ago by Dandello: n/a

Got it:

#!/usr/bin/perl
# $Id: array $
# $Date: 12.08.11 $
# $HeadURL:  $
# $Revision: 2011 $
# $Source: /array.pl $
##################################################################################
use strict;
use warnings;
use CGI::Carp;

our $VERSION = 1.00;

my $filename = 'input.txt';

open my $DAT, '<', $filename or croak 'cannot open file';
my @dataa = <$DAT>;
close $DAT or croak 'cannot close SFILE';
my %out  = ();
my %out2 = ();
my @in   = ();
my @out  = ();
my @out2 = ();
my $rec  = {};
my $cn   = 0;
foreach my $i (@dataa) {
    chomp $i;
    @in = split /[|]/xsm, $i;
    $out[$cn] = $in[2] . q{:} . $i;
    my ( $keya, $rest ) = split /[:]/xsm, $out[$cn];
    $out2{$keya} = $rest;
    $cn++;
}

open my $DATABASE, '>', 'output.txt' or croak 'array not made.';
foreach my $key ( sort keys %out2 ) {
    print {$DATABASE} "$out2{$key}\n" or croak 'cannot print to database';
}
close $DATABASE or croak 'array not closed.';

exit;

Hashes are not my strong suit - so this is clumsy but it does work.

Here's an example of sorting an array by a specified column.

#!/usr/bin/perl;
use strict;
use warnings;

my @array = sort howtosort <DATA>;

foreach (@array){
    chomp;
    print "$_\n";
}

sub howtosort{
    my @flds_a = split(/\|/, $a);
    my @flds_b = split(/\|/, $b);
    $flds_a[2] cmp $flds_b[2]; #compare key fields to sort
}
__DATA__
1780438|20110709|0000007704000000000000004888|7704|48881|PE|08/12/2008 11:38:54|0|1000.00
1780437|20110708|0000007704000000000000004882|7704|48882|PE|08/12/2008 11:38:54|0|1000.00
1780436|20110707|0000007704000000000000004889|7704|48887|PE|08/11/2008 11:38:54|0|1000.00
1780435|20110703|0000007704000000000000004881|7704|48888|PE|08/12/2008 11:38:54|0|1000.00
Comments
Done wonderful
This question has already been answered. Start a new discussion instead.