http://www.perlmonks.org?node_id=390050

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

Dear Perl Monks,

I have an input file with numbers seperated in <sep> tags. i want the sorting to happen only inside those tags.

e.g.
input

<sep> 22 1 3 <sep> 4 2 44
output should be like
<sep> 1 3 22 <sep> 2 4 44

my following scripts sorts but not with in the sep tags.

open(IN, "<sort.in") || die "\nCan't open ap3.07 \n"; open(OUT, ">sort.out"); @array=<IN>; close (IN); @sortedarray=sort {$a <=> $b} (@array); foreach $line (@sortedarray){ print OUT $line; } close(IN); close(OUT);

pls help me in doing this

Replies are listed 'Best First'.
Re: sorting inside specific
by Limbic~Region (Chancellor) on Sep 10, 2004 at 13:29 UTC
    texuser74,
    If you take a look at perldoc perlvar you will find plenty of interesting variables to make you life easier. In this case, I used $/ - the input record seperator.
    $/ = "<sep>\n"; while ( <DATA> ) { chomp; print "$_\n" for sort { $a <=> $b } split /\n/; print $/ if ! eof DATA; }

    Cheers - L~R

Re: sorting inside specific
by Arunbear (Prior) on Sep 10, 2004 at 13:54 UTC
    use strict; use warnings; my @data; # this will be an array of arrays while(<DATA>) # read from __DATA__ for simplicity { chomp; if($_ eq '<sep>') { push @data, [] } else { push @{$data[-1]}, $_ } } foreach (@data) { print "<sep>\n", join("\n", sort { $a <=> $b } @$_), "\n"; } __DATA__ <sep> 22 1 3 <sep> 4 2 44
    Output:
    <sep> 1 3 22 <sep> 2 4 44 Tool completed successfully
Re: sorting inside specific
by svsingh (Priest) on Sep 10, 2004 at 13:35 UTC
    You probably just need to split your data into blocks. Once you do that, sort the values in each block.

    use strict; use Data::Dumper; undef $/; # read all data my @sets = split('<sep>\s', <DATA>); # split by block foreach (@sets) { my @values = split /\s/; # get each value in block my @sorted = sort { $a<=>$b } @values; print Dumper(\@sorted); }
Re: sorting inside specific
by Random_Walk (Prior) on Sep 10, 2004 at 13:30 UTC
    As long as there is only one
    <sep> <sep>
    pair
    perl -lne'print unless$s;push@s,$_ if$s;if(/<sep>/){if($s){foreach(sor +t @s){print}$s=0}else{$s+=1}}'

    This is a bit quick and dirty as the last tag is included in the sort (no prob if the items to be sorted are all numeric)

    Cheers,
    R.
Re: sorting inside specific
by mutated (Monk) on Sep 10, 2004 at 13:25 UTC
    This is nothing special but it should work...
    open(IN, "<sort.in") || die "\nFailed to open infile $?\n"; open(OUT,">sort.out"); my @array; while(<IN>) { if (/<SEP>/) { print OUT join '',sort {$a <=> $b} @array; print OUT "<SEP>\n"; @array=(); } else { @array = (@array,$_); } } print OUT join '',sort {$a <=> $b} @array; close OUT; close IN;
    UPDATE: Got rid of errors to occur when run with use strict and use warnings


    daN.
      mutated,
      but it should work

      Really? AFAICT it isn't even close. What exactly is sort numerically @array supposed to do? At what point are you storing anything in @array? Even after fixing your coding mistakes (strictures and warnings)++ - all I get for output is:

      <sep> <sep>

      Cheers - L~R

      Update: Even your updated code is broke. I preserved your original code in HTML comments. You would see the problem if you had warnings and strictures on
      Update 2: Good job! Not exactly the way I would have done it, but it works ;-)
        No worries, I should have tested before I posted in the first place..too early and no morning coffee..sigh..at any rate it works now :P..it's still not as eloquent as your solution but I'm learning...still trying rap my head around the sort function


        daN.

      Take a look at push.

      @array = (@array,$_); # copies the entire array every time
      push @array, $_; # does not copy the entire array every time