Anish has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to sort file below using code below.I'm sorting this file by character 7 to 11 (i.e in first line it is TO1BD),which it does.After sorting I want to do is number each line.for e.g. in first line I want to replace 000200 (first six digit ) 000001 and in second line I want to replace first six digit by 000002 and so on. For that I'm trying to use for loop. but its not working.I need suggestion for that...If someone can point to me what am i doing wrong in for loop.. Thanks Input file: 000200T01BDS100000C100001121220001002000000000000006906SQ, 000020T01BWS100000AT01B20000220001002000000000007203267Ele 000190Z80BWS100000C300000155420001002000000000000902500OUTSO 000019B02BWS100000AT01B20000220001002000000000057563144Avaya 000001T01ADS100000C200000213920001002000000000002755000ST
#!/usr/bin/perl open (input, "<SAPPDAY.00063"); open (out, ">SAPPDAY.00063out"); #!/usr/bin/perl #!/usr/bin/perl #!/usr/bin/perl open (IN, "<temp65") or die "couldn't open file for reading"; open (OUT, ">temp95")or die "couldn't open file for writing"; @EDI=<IN>; #$number=$#EDI; close (IN); #$Id=substr($EDI[0],6,5); #print $Id; #print $number; @temp=map{[substr($_,6,5),$_ ]} @EDI; @temp= sort {$a->[0] cmp $b->[0]} @temp; @ordered=map {$_->[1]} @temp; $count=1; #$ele=$#ordered; #print "$ele\n"; for $x (0..$#ordered){ #$num=substr($ordered[$x],3,3); #print "$num is right\n"; $ordered[x]=~s/(substr($ordered[$x],3,3))/$count/; $count++; } print OUT @ordered; close (OUT);

Replies are listed 'Best First'.
Re: Sort and Substitution
by Fastolfe (Vicar) on Oct 24, 2000 at 22:58 UTC
    You may be interested in using substr as part of your search function.
    @sorted = sort { substr($a, 7, 5) cmp substr($b, 7, 5) } @unsorted;
    The trick is in efficiency. You may want to think about expanding this using the Schwartzian Transform if you're dealing with a lot of data:
    @sorted = map { $_->[0] } sort { $a->[1] cmp $b->[1] } map { [ $_, substr($_, 7, 5) ] } @unsorted;
    This does basically the same thing, but all of the substring operations are done first, and done only once. The simpler example involves doing the substr multiple times as each substring is compared against each other substring.
Re: Sort and Substitution
by runrig (Abbot) on Oct 24, 2000 at 22:58 UTC
    For one thing you don't need the '$x' counter in your for loop, and for another you don't need a regex when substr will do:
    $count='000001'; substr($_,0,6)=$count++ for @ordered;
RE: Sort and Substitution
by extremely (Priest) on Oct 25, 2000 at 11:09 UTC
    In that last for loop, you may want to do something more like this:
    foreach $x (@ordered){ substr($x,0,6))=sprintf("%06d", $count++); }

    Now that is a lot to throw at you at once so...

    One, the foreach loop goes thru each item in an array, setting $x to each line in the array. $x really is each row as it goes thru the list so if you change $x you change the array, one line at a time. Very handy for what you want to do. =)

    substr() can easily grab the first 6 characters from $x. You knew that I can see. What you may not have known was, you can assign TO the substr call and it will replace the substr'ing you asked for with what you have on the right side of the '='. Thus you can replace the 6 numerals at the beginning with whatever you want.

    Now on the right side of the equals, sprintf() is likely new to you. It lets you prepare a string for "printing" based on a "format". The format I gave it is "%06d" which means to give me a 6 digit number, padded with zeros, taken from the variable(s) following the format.

    I've given sprintf the output from $count++ . The output from $count++ is the value of $count BEFORE one is added to it. So the first time thru the loop sprintf makes "000001" and $count=2!

    Others have noted that you might have done the sort better and such but really you were doing pretty good. I hope I didn't throw too much at you and I hope it helps!

    --
    $you = new YOU;
    honk() if $you->love(perl)

Re: Sort and Substitution
by snowcrash (Friar) on Oct 25, 2000 at 12:18 UTC
    hi! rather than telling you how you could complete your task in a better way, here is why your substitution doesn't work: the search pattern (substr($ordered[$x],3,3)) is not evaluated as an expression, only $ordered[$x] gets evaluated to its value. so you are trying to substitute a string like "(substr(1243234123411224,3,3))" that $ordered[$x] doesn't contain. to illustrate what happens:
    my $foo = "12342343432424232"; my $bar = "substr12342343432424232,3,3"; $foo =~ s/(substr($foo,3,3))/fnord/; $bar =~ s/(substr($foo,3,3))/fnord/; print "foo: $foo\n"; print "bar: $bar\n";

    the code above prints:
    foo: 12342343432424232 bar: fnord
    yt, snowcrash