Solved

Sorting & displaying a file.

Posted on 2000-03-24
6
228 Views
Last Modified: 2011-09-20
The following code snppet opens a flat file with a list of 4 pipe delimited fields terminated with a new line and displays them in sequential order.

QUESTION:

How would I display the file contents say, SORTED on field 1 ($f1) and NOT sequentially ????

I would like a working code example.
Thanks, In advance.

#!/usr/bin/perl

$dbase = "/home/blah/dbase.txt";

print "Content-type: text/html\n\n";
print "<html><head><title></title></head>\n";
print "<body bgcolor=#FFFFFF\n";
print "<br>\n";

open(FILE,"$dbase") || die "Cannot Open Database File: $!\n";

&dall;

print "<br></body></html>\n";
close(FILE);
exit;

# Display all records
sub dall {
 while(<FILE>) {
 chop;
 @all = split(/\n/);
  foreach $line(@all) {
   local($f1,$f2,$f3,$f4)=split (/|/,$line);
   &display;
  }
 }
}

# Display results
sub display {
print "$f1, $f2, $f3, $f4\n";
print "<br>\n";
}

0
Comment
Question by:haast
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
6 Comments
 
LVL 16

Accepted Solution

by:
maneshr earned 200 total points
ID: 2656112
here is your modified script

the sort sub routine i have provided is very flexible. using this you can sort on any column numerically or alphabetically, in ascending or descending order.

=====================================
#!/usr/bin/perl

$dbase = "/home/blah/dbase.txt";

print "Content-type: text/html\n\n";
print "<html><head><title></title></head>\n";
print "<body bgcolor=#FFFFFF\n";
print "<br>\n";

open(FILE,"$dbase") || die "Cannot Open Database File: $!\n";
@all=<FILE>; ## Read the entire file into an array. every line of the file is
## an element in the array.
close(FILE);

##  Column num (starting from 1), type of sort
##  n = numeric, a = alphabetic ...
##  ... Sort order "a" = ascending, "d"= descending & ...
##  ... Array to sort
@all=&my_sort(1,"n","d",@all);

foreach $line(@all) {
  local($f1,$f2,$f3,$f4)=split (/|/,$line);
  print "$f1, $f2, $f3, $f4\n";
  print "<br>\n";
}

print "<br></body></html>\n";

##  Subroutine that does the actual sort.
##  Accepts 4 params viz. the column number to sort
##  Column no starts with 1. The type of sort numeric or alphabetic
##  Finally the sort order is required. Default order is ascending
##  The array that needs to be sorted.
sub my_sort{
  ($col,$type,$sort_order,@arr)=@_;

  ##  Deduct 1 from the column.
  ##  We do this because in PERL array subscript starts with 0.
  ##  So in human terms when we say column 2 it means column 1 in PERL terms!!
  $col--;

  ##  To take care of conditions where user has passed anything other
  ##  ... than a "n" or "N". Eg. if the user has said &my_sort(3,"z",@array,"a"
), we ignore the z and perform an alphabetic sort ("a").
  $type="a" if $type!~ /^n$/i;  ##  Default Alphabetic sort

  ##  To take care of conditions where user has passed anything other
  ##  ... than a "d" or "D". Eg. if the user has said &my_sort(3,"z",@array,"q"
), we ignore the q and sort in ascending order("a").
  $sort_order="a" if $sort_order!~ /^d$/i;  ##  Default Ascending Sort order

  ##  Process every element of the array
  foreach(@arr){
    ##  Split every line using | as the delimiter.
    @tmp=split(/\|/,$_);
    ##  After we split we know how many columns are ..
    ##  ... present in every record. Now we have to ...
    ##  ... take care of situations where the user might want ..
    ##  ... to sort on non-existant or invalid columns.
    ##  Eg. Each record has 6 columns and the user has passed 7 or 8
    ##  ... or -1 etc...

    return 0 if ($col<0 || $col>(scalar @tmp)); ## Invalid col no.

    ##  This is important. We take the column that the user wants ...
    ##  ... to sort on and pre-pend it to the record itself.

    ##  Let's say the record is ...
    # Toronto|Jeff|jeff@hyrum.net|98|571803
    ##  ...& the user wants to sort on the 2nd column (PERL subscript 1).
    $new_arr=join('|',$tmp[$col],$_);
    ##  After the above the record will be...
    # Jeff|Toronto|Jeff|jeff@hyrum.net|98|571803

    ##  Store this new record in an array
    push(@new_arr,$new_arr);
  }

  ##  Determine the type of sort
 if ($type=~ /^n$/i){    ##  Numeric Sort
    if ($sort_order=~ /^d$/i){  ##  Descending sort requested
      ##  Sort the array by number using the bynum subroutine
      @new_arr=reverse sort bynum @new_arr
    }else{  ##  Default, Ascending sort order requested
      @new_arr=sort bynum @new_arr
    }
  }else{  ##  Alphabetic sort
    if ($sort_order=~ /^d$/i){  ##  Descending sort requested
      ##  Sort the array by alphabets using the byalp subroutine
      @new_arr=reverse sort byalp @new_arr
    }else{  ##  Default, Ascending sort order requested
      @new_arr=sort byalp @new_arr
    }
  }

  @arr="";  ##  Re initialize the array
  ##  Remember our sort is done, but we still have that...
  ##  ...extra column at the beggining that we must remove!!
  foreach(@new_arr){
    ##  Split every line using | as the delimiter.
    @tmp=split(/\|/,$_);
    shift(@tmp);  ##  Remove that 1st column
    ##  So before the shift if we had....
    # Jeff|Toronto|Jeff|jeff@hyrum.net|98|571803
    ##  After th shift we will have...
    # Toronto|Jeff|jeff@hyrum.net|98|571803

    ##  Join the array as one record...
    $new_arr=join('|',@tmp);
    ##  ...& store it in another array.
    push(@arr,$new_arr);
  }

  ##  Return the final array (in sorted order)
  return @arr;
}

sub bynum{ $a <=> $b;}

sub byalp{ $a cmp $b;}
0
 

Author Comment

by:haast
ID: 2656220
Hang on, I will try it.....
0
 

Author Comment

by:haast
ID: 2656253
Maneshr, that is excellent, I want to award you the points for this.

I am a newbie and I really appreciate your help, I would like to ask you ONE more question, and either add 100 more points to this or ask a NEW one (please advise !!!!).

It is a variation on my original one.

#!/usr/bin/perl

$dbase = "/home/blah/dbase.txt";

# Parse Form
read(STDIN, $input, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $input);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$name =~ tr/+/ /;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}

# Translate Hash References
$find  = $FORM{'term'};

print "Content-type: text/html\n\n";
print "<html><head><title></title></head>\n";
print "<body bgcolor=#FFFFFF\n";
print "<br>\n";

open(FILE,"$dbase") || die "Cannot Open Database File: $!\n";

&search;

print "<br></body></html>\n";
close(FILE);
exit;

# Search all records for matches
sub search {
$match = 0;
 while(<FILE>) {
 chop;
 @all = split(/\n/);
  foreach $line(@all) {
   local($f1,$f2,$f3,$f4)=split (/|/,$line);

    if($find eq $f1){
      &display;
    }
  }
 }
}

# Display matched results
sub display {
print "$f1, $f2, $f3, $f4\n";
print "<br>\n";
}

-------------------
MY NEW QUESTION IS:

How would I sort the results of the matched records ($find eq $f1) , and display them say, in ascending alfa sorted order based on field $f2.

Thanks !!!!






0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:haast
ID: 2656256
Adjusted points from 100 to 200
0
 

Author Comment

by:haast
ID: 2657268
Maneshr, even if you do not answer the second part of my question, please collect your points. Your help is much appreciated.
0
 

Author Comment

by:haast
ID: 2657634
Maneshr, I have figured my second question out, PLEASE collect your points.

Thanks !!
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

730 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