Solved

Ordering Values...

Posted on 2000-05-15
9
220 Views
Last Modified: 2010-03-05
I am working on a script to process entries from a form and print out an address book, it doesn't hve to be particularly effective but I want to be able to print out 2 files, the first ordered by name, the second ordered by town...

The values are currently passed out into a control file, delimeded by |%%| with each entry on a new line e.g.

add0|%%|$add1|%%|$add2|%%|$add3|%%|$add4|%%|$add5

As I said I would want to print out 2 files, one with each line listed by name (add0) in alphabetical order, the second listed by town (add5) in alphbetical order...
0
Comment
Question by:JavaBloggs
  • 4
  • 3
  • 2
9 Comments
 
LVL 16

Expert Comment

by:maneshr
ID: 2811368
i am not clear of your exact requirements.

i have a couple of Q's for you.

* so do you already have a file where you have stored the users info and now you want to sort that same file and write the output to 2 diff files (one by name & other by town)??

* or do you want to take users input from the HTML form, store it in a file and then create 2 files, one sorted by name and other by town??

Also can you provide a sample file, if you have one??

Rgds
0
 

Author Comment

by:JavaBloggs
ID: 2811421
Okay...
I wanna take users input from HTML and store it in a file and then create the 2 ordered files from that...

What I have got so far is:
#!/bin/perl

print "Content-type: text/html\n\n";

$GABpage="http://www.gen.hobsons.com/forum/book.shtml";
$GABssif="results.htm";
$GABctrl="gabctrl.dat";

&parse_form;

$red=$ENV{'HTTP_REFERRER'};
$red="$GABpage";

$method=$ENV{'REQUEST_METHOD'};
if ($method !~ /POST/i) {
  print "Location: $red\n\n";
  exit;
}

open(CTRL, "<$GABctrl") or explode ("Cannot open control file at line 21 - $!");
      push @contents, <CTRL>;
close(CTRL);

$add0 = $FORM{'Title'};
$add0 =~ s/(\n|\r|\t)/ /isg;
$add1 = $FORM{'Firstname'};
$add1 =~ s/(\n|\r|\t)/ /isg;
$add2 = $FORM{'Surname'};
$add2 =~ s/(\n|\r|\t)/ /isg;
$add3 = $FORM{'Jobtitle'};
$add3 =~ s/(\n|\r|\t)/ /isg;
$add4 = $FORM{'Field'};
$add4 =~ s/(\n|\r|\t)/ /isg;
$add5 = $FORM{'company'};
$add5 =~ s/(\n|\r|\t)/ /isg;
$add6 = $FORM{'Region'};
$add6 =~ s/(\n|\r|\t)/ /isg;
$add7 = $FORM{'Country'};
$add7 =~ s/(\n|\r|\t)/ /isg;
$add8 = $FORM{'Business'};
$add8 =~ s/(\n|\r|\t)/ /isg;
$add9 = $FORM{'Email'};
$add9 =~ s/(\n|\r|\t)/ /isg;

open(CTRL, ">>$GABctrl") or explode ("Cannot open control file at line 45 - $!");
      print CTRL "$add0|%%|$add1|%%|$add2|%%|$add3|%%|$add4|%%|$add5|%%|$add6|%%|$add7|%%|$add8|%%|$add9\n";
close(CTRL);

Sorry, know its not great  :o(  just generates a file I can perorm a split on...

0
 
LVL 12

Expert Comment

by:geotiger
ID: 2811508
Although it is not a pure Perl answer, it will serve your purpose assuming you are working in a unix environment:
$fn = "/full/dir/to/your/addr/file";
$out_fn1 = "/output/file/name1";
$out_fn2 = "/output/file/name2";

$sort_byname = "cat $fn | sort ";

open FILE, "$sort_byname |" or die "could not run $sort_byname:$!\n";
open OUT1, ">$out_fn1" or die "could not write to $out_fn1:$!\n";
while (<FILE>) { print OUT1 $_; }
close FILE;

$sort_bytown = "cat $fn | sed -e 's/\|\%\%\|/\|/g' | sort -t\| -k 6,6 ";
open FILE, "$sort_bytown |" or die "could not run $sort_bytown:$!\n";
open OUT2, ">$out_fn1" or die "could not write to $out_fn2:$!\n";
while (<FILE>) { print OUT2 $_; }
close FILE;

If you are looking for pure Perl, solution, you need to use "cmp" function to do the comparison.

0
 
LVL 12

Expert Comment

by:geotiger
ID: 2811521
Forgot to close the two output files. Please add the following:

close OUT1;
close OUT2;

0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 16

Accepted Solution

by:
maneshr earned 285 total points
ID: 2811786
here is a perl based solution for sorting your file and getting the results.

The advantages of this method are as follows :-

* based entirely in PERL. therefore portable.
* can be used to sort of ANY column.
* sort can be specified (alphabetical or numeric.)
* sort order can be specified (ascending or descending)
* modular, therfore can be used in ANY other program.

Add the code after all your processing is done. i.e. after....

print CTRL
"$add0|%%|$add1|%%|$add2|%%|$add3|%%|$add4|%%|$add5|%%|$add6|%%|$add7|%%|$add8|%%|$add9\n";
close(CTRL);

## PERL code to sort and store.
$GABctrl_by_name="gabctrl_by_name.dat";
$GABctrl_by_town="gabctrl_by_town.dat";

open(CTRL, "$GABctrl") or explode ("Cannot open control file at line ?? - $!");
@GAB=<CTRL>;  ## Read the entire file in an array!!
close (CTRL);


@GAB_by_name=&my_sort(2,"a","a",@GAB); ## Assuming name is the 2nd col, do a alphabetical ascending order sort.
@GAB_by_town=&my_sort(3,"a","d",@GAB); ## Assuming town is the 3rd col, do a alphabetical descending order sort.

## Write the output to the respective files!!
open(CTRL, ">$GABctrl_by_name") or explode ("Cannot open control file at line ?? - $!");
foreach(@GAB_by_name){
  print CTRL $_;
}
close(CTRL);

open(CTRL, ">$GABctrl_by_town") or explode ("Cannot open control file at line ?? - $!");
foreach(@GAB_by_town){
  print CTRL $_;
}
close(CTRL);

###############################################
##  Subroutine that does the actual sort.
##  Accepts 4 params viz. the column number to sort
##  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","a",@array), 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","q",@array), 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
    }
  }

  undef @arr;
  ##  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:JavaBloggs
ID: 2813669
Thanks very much for that one...

Its working brilliantly, and I lernt a fair bit from it  :o)

There was one minor problem, its academic now as I have split the processes up, but the second ordered set your code put out had the entries in twice (presumably because @new_arr still had the old values in it)...

Regards
From
Me
!

0
 
LVL 16

Expert Comment

by:maneshr
ID: 2813981
"......There was one minor problem, its academic now as I have split the processes up, but the second ordered set your code put out had the entries in twice (presumably because @new_arr still had the old values in it)... ...."

Sorry. my mistake!! :-0



Pl. add the foll line........

undef @new_arr;

BEFORE....

##  Return the final array (in sorted order)

that should fix it.

Rgds
0
 

Author Comment

by:JavaBloggs
ID: 2814357
Nice one, cheers yet again  :o)

It is now happy, bouncy, funkey and cool... and will keep me going till I get SQL sorted  :o)

Regds
me
0
 
LVL 16

Expert Comment

by:maneshr
ID: 2814718
Cool!!

Wish you luck with your project!!

Rgds
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Suggested Solutions

In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (http://dilbert.com/strips/comic/2007-08…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
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…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

757 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

21 Experts available now in Live!

Get 1:1 Help Now