Reputation: 3
My data file is like this:
* jsdklfjsldkfjlsdkfj
*.AW=351 Tb=sdf c=132 d=53135 s=sdlkfj
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 7
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 3
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 8
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 4
* jsdklfjsldkfjlsdkfj
*.AW=351 Tb=sdf c=132 d=53135 s=sdlkfj
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 7
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 3
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 8
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 4
The Perl code that I have so far is as follows:
open (my $file, "data.txt");
@data=<$file>;
close ($file);
open ($file, ">","data2.txt");
for (@data,undef) {
if (defined && /^\:.*(\d+)\n/) {
push @a, [$1,$_];
next }
print $file $_->[1]
for sort { $a->[0] <=> $b->[0] }
splice @a;
print $file $_ if defined ;
}
close ($file);
I'm not sure how to find the last number and rank it from small to large.
The same data sorted by rank is like this (Final format):
* jsdklfjsldkfjlsdkfj
*.AW=351 Tb=sdf c=132 d=53135 s=sdlkfj
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 3
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 4
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 7
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 8
* jsdklfjsldkfjlsdkfj
*.AW=351 Tb=sdf c=132 d=53135 s=sdlkfj
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 3
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 4
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 7
: A CC=(111.153.781.36), DD=(111.153.781.36), (sdf_sdf) = 8
Upvotes: 0
Views: 105
Reputation: 52529
Something like:
#!/usr/bin/env perl
use strict;
use warnings;
use autodie;
open my $data, "<", "data.txt";
open my $out, ">", "data2.txt";
my @lines;
while (my $line = <$data>) {
if ($line =~ /^\* number/) {
print $out $_->[1] for sort { $a->[0] <=> $b->[0] } @lines;
@lines = ();
print $out $line;
} elsif ($line =~ /^\*/) {
print $out $line;
} elsif ($line =~ /^:/ && $line =~ /\s+(\S+)\s*$/) {
push @lines, [$1, $line];
} else {
die "Unknown line! $line";
}
}
close $data;
close $out;
The key bit is the print $out $_->[1] for sort { $a->[0] <=> $b->[0] } @lines;
lines, which print out the actual lines after sorting by the number at the end.
Upvotes: 3
Reputation: 62154
Your regex is too greedy. This is less greedy:
if ( defined && /^\:.*=\s+(\S+)\n/ ) {
If you print the contents of @a
before you print to your output file, you will see that it contains only the last digit (0), rather than the whole sci-not number (3.21533e-10), for example.
Upvotes: 0