Solved

Sorting text as numbers

Posted on 2013-11-27
20
363 Views
Last Modified: 2013-11-27
I have a list of values which I need to sort in descending order, of the first column, and keep the relational integrity with the second column.

The problem is that this data in the second column is not numerical, I need to retain the "0" at the front (if it is present)

So this sample list:

03210 54000
12300 48600
20202 72900
23010 43200
02220 91125
03201 54000

would be sorted to look like this :

23010 43200
20202 72900
12300 48600
03210 54000
03201 54000
02220 91125

Could someone help me with code that would do this please ?
0
Comment
Question by:MichaelGlancy
  • 10
  • 6
  • 4
20 Comments
 
LVL 84

Expert Comment

by:ozo
ID: 39682088
@list=reverse sort <DATA>;
print @list;
__DATA__
03210 54000
12300 48600
20202 72900
23010 43200
02220 91125
03201 54000
0
 

Author Comment

by:MichaelGlancy
ID: 39682100
thanks

forgot to mention, i need it in a .pl file :)
0
 
LVL 84

Expert Comment

by:ozo
ID: 39682109
cat > sort.pl <<END
#!/usr/bin/perl
use strict;
use warnings;
my @list=reverse sort <DATA>;
print @list;
__DATA__
03210 54000
12300 48600
20202 72900
23010 43200
02220 91125
03201 54000
END
0
 
LVL 26

Expert Comment

by:wilcoxon
ID: 39682115
If for some reason, the simple sort doesn't always work, you can define a custom sort function...
@list=sort col1_rev <DATA>;
print @list;
sub col1_rev {
    # split the columns and only compare the first one
    my @cola = split /\s+/, $a;
    my @colb = split /\s+/, $b;
    return $colb[0] <=> $cola[0];
}
__DATA__
03210 54000
12300 48600
20202 72900
23010 43200
02220 91125
03201 54000

Open in new window

0
 

Author Comment

by:MichaelGlancy
ID: 39682116
is this what I have to do ?

cat > sort.pl <<END
#!/usr/bin/perl
use strict;
use warnings;
my @list=reverse sort <DATA>;
print @list;
__DATA__
03210 54000
12300 48600
20202 72900
23010 43200
02220 91125
03201 54000
15000 2268
13200 48600
10122 182250
11004 18900
20112 162000
01401 21000
20031 43200
11103 108000
32010 37800
50001 1260
22011 162000
00015 2520
05100 2520
21201 162000
00501 2520
12102 182250
00006 210
03120 54000
20103 43200
00510 2520
02022 91125
22002 72900
01014 21000
40002 5670
04020 9450
13110 108000
02301 54000
10401 18900
01122 202500
12021 182250
21102 162000
03300 14400
00321 54000
10032 48600
41010 12600
02202 91125
10005 2268
02400 9450
10050 2268
40011 12600
20013 43200
00600 210
11121 405000
40200 5670
31011 84000
20310 43200
20121 162000
01104 21000
00213 54000
14010 18900
00132 54000
12003 48600
31101 84000
40101 12600
30111 84000
60000 84
21210 162000
00420 9450
30003 10080
04101 21000
32100 37800
10113 108000
20004 7560
03012 54000
22200 72900
10203 48600
12120 182250
00150 2520
01320 54000
30210 37800
03003 14400
13020 48600
23100 43200
01410 21000
30120 37800
20301 43200
20130 43200
02211 202500
00123 54000
01203 54000
00114 21000
10131 108000
12111 405000
41001 12600
11031 108000
22101 162000
22020 72900
21003 43200
20022 72900
02031 54000
10140 18900
11112 405000
00141 21000
00411 21000
01032 54000
41100 12600
31110 84000
01500 2520
11220 182250
00204 9450
12201 182250
11013 108000
06000 210
00060 210
11211 405000
14100 18900
12012 182250
22110 162000
14001 18900
11022 182250
01230 54000
21300 43200
12030 48600
01131 120000
01221 202500
00303 14400
02121 202500
01113 120000
30030 10080
20220 72900
01041 21000
42000 5670
10500 2268
02103 54000
10041 18900
01302 54000
24000 7560
31200 37800
11301 108000
04011 21000
00105 2520
10014 18900
02013 54000
02040 9450
02112 202500
10311 108000
05010 2520
03021 54000
30201 37800
21111 360000
10320 48600
00402 9450
30012 37800
04002 9450
21120 162000
20211 162000
11202 182250
10230 48600
03030 14400
04200 9450
13011 108000
00330 14400
02310 54000
30102 37800
30021 37800
20040 7560
32001 37800
11310 108000
00024 9450
00231 54000
40020 5670
11400 18900
10221 182250
00042 9450
00222 91125
01050 2520
03111 120000
31020 37800
02004 9450
00240 9450
01140 21000
30300 10080
12210 182250
10104 18900
00312 54000
10302 48600
00033 14400
01212 202500
11130 108000
00051 2520
21012 162000
23001 43200
10410 18900
21021 162000
05001 2520
40110 12600
13101 108000
04110 21000
50100 1260
03102 54000
10212 182250
01005 2520
21030 43200
02130 54000
31002 37800
51000 1260
10023 48600
20400 7560
33000 10080
50010 1260
11040 18900
01311 120000
13002 48600
01023 54000
END

and run it as a .pl file ?
0
 
LVL 26

Expert Comment

by:wilcoxon
ID: 39682136
No.  You can just read in a file.  Here's a modification of my script to do either...
use strict;
use warnings;
my @list;
my $fil = shift;
if ($fil) { # real
    open IN, $fil or die "could not open $fil: $!";
    @list = <IN>;
    close IN;
} else { # sample
    @list = <DATA>;
}
print sort col1_rev @list;
sub col1_rev {
    # split the columns and only compare the first one
    my @cola = split /\s+/, $a;
    my @colb = split /\s+/, $b;
    return $colb[0] <=> $cola[0];
}
__DATA__
03210 54000
12300 48600
20202 72900
23010 43200
02220 91125
03201 54000

Open in new window


To read in and sort a file, just call it as:
script.pl file_to_sort
0
 

Author Comment

by:MichaelGlancy
ID: 39682143
ok so I run script.pl file_to_sort

so why is this

__DATA__
03210 54000
12300 48600
20202 72900
23010 43200
02220 91125
03201 54000

in the example you gave ?
0
 

Author Comment

by:MichaelGlancy
ID: 39682146
oh and Im not great at the command prompt. If I could have it as a standalone .pl file which opens the sample.txt and sorts it to another file output.txt that would be great :)
0
 
LVL 26

Expert Comment

by:wilcoxon
ID: 39682154
The __DATA__ section was left in for no particular reason.  Here's a version to remove the __DATA__ section and always read sample.txt.
use strict;
use warnings;
open IN, 'sample.txt' or die "could not open sample.txt: $!";
my @list = <IN>;
close IN;
print sort col1_rev @list;
sub col1_rev {
    # split the columns and only compare the first one
    my @cola = split /\s+/, $a;
    my @colb = split /\s+/, $b;
    return $colb[0] <=> $cola[0];
}

Open in new window

0
 
LVL 84

Expert Comment

by:ozo
ID: 39682160
Yes, although since the second column has different widths, if the second column is ever needed to determine the sort order, I'm not sure whether the order will be quite the order you want.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:MichaelGlancy
ID: 39682170
ozo - the second column will never be used to determing sort order. The second row is the frequency of values found in my original sort.

wilcoxon - I ran that code as sort.pl and the list was in output.txt.

Something happened, the window appeared and I could see it running through something. But I reopened output.txt and nothing had changed ?


Sorry guys Im a complete novice at this,
0
 
LVL 84

Accepted Solution

by:
ozo earned 500 total points
ID: 39682176
#!/usr/bin/perl
use strict;
use warnings;
@ARGV or @ARGV=('sample.txt');
open STDOUT,">output.txt" or die "output.txt $!";
print reverse sort <>;
0
 

Author Comment

by:MichaelGlancy
ID: 39682180
still no sorting :(
0
 
LVL 84

Expert Comment

by:ozo
ID: 39682194
Are you saying that after running http:#a39682176
output.txt was identical to sample.txt?
0
 

Author Comment

by:MichaelGlancy
ID: 39682262
ozo - yes, I put that code in a file, ran it and no change to sample.txt
0
 
LVL 84

Expert Comment

by:ozo
ID: 39682267
You asked for code which opens the sample.txt and sorts it to another file output.txt
so the sorted output would be in output.txt, and  sample.txt would not change.
0
 

Author Comment

by:MichaelGlancy
ID: 39682273
0
 

Author Comment

by:MichaelGlancy
ID: 39682276
it is, thankyou. :)
0
 
LVL 26

Expert Comment

by:wilcoxon
ID: 39682412
Yes.  My code output to the screen (which then closed).  I missed the outputting to output.txt.
use strict;
use warnings;
open IN, 'sample.txt' or die "could not open sample.txt: $!";
my @list = <IN>;
close IN;
open OUT, '>output.txt' or die "could not write output.txt: $!";
print OUT sort col1_rev @list;
sub col1_rev {
    # split the columns and only compare the first one
    my @cola = split /\s+/, $a;
    my @colb = split /\s+/, $b;
    return $colb[0] <=> $cola[0];
}

Open in new window


Considering that both ozo and I provided lots of responses, I would have hoped you would split the points between us.
0
 

Author Comment

by:MichaelGlancy
ID: 39682451
wilcoxon - I apologise. Ozo gave me a solution that worked straight away for me. I will be more considerate in future.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

This is about my first experience with programming Arduino.
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
This video teaches viewers about errors in exception handling.
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now