match regexp help

Discuss Programming
User avatar
Void Main
Site Admin
Site Admin
Posts: 5712
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Wed Aug 03, 2005 8:12 pm

Well, your PREF variable contains "ad" so that together with "info.info" makes "adinfo.info".

worker201
guru
guru
Posts: 668
Joined: Sun Jun 13, 2004 6:38 pm
Location: Hawaii

Post by worker201 » Wed Aug 03, 2005 9:31 pm

Well yeah. But the curly braces, they separate the $ from PREF, so it seems like it would do something else.

Also, is there any way to round a number to the nearest multiple of 10? Like, if I had 157.34 and 34.9 as ranges to plot, how could I set this range as 160 and 30? I know enough now to get the numbers into memory, but I don't know if the shell script is smart enough to round up or down.

User avatar
Void Main
Site Admin
Site Admin
Posts: 5712
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Wed Aug 03, 2005 10:08 pm

You can probably write a word processor in shell script if you try hard enough, but it just doesn't make a lot of sense. What you're getting in to is really simple Perl scripting. I would make the jump if I were you. You can learn it a little at a time.

To answer your question about the curly brackets, they are necessary to distinguish your variable name $PREF otherwise the shell would interperet $PREFinfo as your variable which would not have been defined anywhere and thus be blank. ${} around your variable name makes the shell know that it is PREF that is the variable.

Your script in Perl:

Code: Select all

#!/usr/bin/perl -w

use strict;

# Command line variables
my $pref  = $ARGV[0];
my $grid  = $ARGV[1];
my $range;

$pref =~ s/poly\.xy//;
my $infofile = $pref . "info.info";
print $infofile . "\n";

system("grdinfo $grid > $infofile");

open(INFO,"<$infofile");
while (<INFO>) {

   if (/Command/) {

      s/.*-R(.*) -I.*//;
      $range = $1;

   }

}
close(INFO);

print $range . "\n";
Doing math is much easier in Perl. I could be wrong but I don't think bash is capable of floating point math directly (korn shell is). If I were to do it in bash I would pipe in commands to the "bc" command. But rather than trying to figure that out I would just do it in Perl. For example:

Code: Select all

#!/usr/bin/perl -w

use strict;

my $v1 = 157.34;
my $v2 = 34.9;

$v1 = int($v1 / 10 + .5) * 10;
$v2 = int($v2 / 10 + .5) * 10;

print "v1: $v1 - v2: $v2\n";

ZiaTioN
administrator
administrator
Posts: 460
Joined: Tue Apr 08, 2003 3:28 pm
Contact:

Post by ZiaTioN » Thu Aug 04, 2005 7:46 am

Your first question in perl:

If the "-R" is not part of the desired variable:

Code: Select all

print /-R(.+?)\s+/ while <>;
If the "-R" is part of the desired variable:

Code: Select all

print /(-R.+?)\s+/ while <>;
I simply printed value to STDOUT here but it can be used any number of ways.

As for rounding goes there are numerous ways to do this as with everything in perl. A few are:

Code: Select all

print int($int + .5);

Code: Select all

($whole, $rem) = split(/\./, $int+.5);
print $whole;
But probably the best way would be:

Code: Select all

print int($int + .5 * ($int <=> 0));
The above handles positive and negative numbers. An explanation of why it handles positive and negative numbers is simple. It is because of the <=> comparision function. This function is special because it returns one of three values. They are -1, 0 or 1. If the variable is equal to 0 then it returns a 0. If the variable is less then 0 then it returns a -1 and if the variable is greater than 0 it returns a 1. So by multiplying the integer value with the return of this function it converts the integer to the proper format.

User avatar
Void Main
Site Admin
Site Admin
Posts: 5712
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Thu Aug 04, 2005 7:49 am

Except he wanted it rounded to the nearest 10 which is why I divided by 10 before rounding and then multiplied the result by 10 which gives him the result he was after. :)

worker201
guru
guru
Posts: 668
Joined: Sun Jun 13, 2004 6:38 pm
Location: Hawaii

Post by worker201 » Thu Aug 04, 2005 4:11 pm

I decided not to do the rounding, since I needed to have the program work today. And now it does! Here's the final version, documented and all. The documentation is pointless, since I am the only person who will ever use this, but I went ahead and did it anyway :P The code could probably be streamlined and more efficient, but not today. Next time.

Code: Select all

#!/bin/bash
# This version finalized August 4, 2005
# Written by Leigh Holcombe, Texas A&M University, Oceanography Department
# Special thanks to VoidMain for regexp assistance
#
# Creates a GMT histogram for an underwater geographic area, which can be used to
# analyze historic trends in sealevel and other such things.  The histogram is produced
# automatically, using base values extracted from the dataset.
#
# Usage: histogrammar [polygon file] [gridfile]
# requires a bash shell, awk, sed, and a local installation of GMT
#
# Arguments: this script expects only 2 arguments, a gridfile, and a polygon file.
#
# The polygon file should be a 2 column ASCII list of floating point values, with the first
# column being decimal longitude, and the second column being decimal latitude. The values 
# should describe an enclosed geographic area.  Note that the polygon must be completely
# above sealevel or below sealevel - ie, it must not cross zero meters, or the zero data will
# be lost.  The polygon's name should be a string designating its location, followed by
# "poly.xy".  As an example, featurenamepoly.xy.  Any other naming convention will fault the
# program.
#
# The gridfile should be a NetCDF gridfile of the elevations or depths of the area of
# interest.  Currently, the program is setup to only accept grids of 1/4 second cellsize,
# but that may change as needed.  
#
# Output: an Encapsulated PostScript (EPS) file which will produce a 12-inch plot of the
# polygon, with the form featurenamepoly.ps, and an EPS file of a 24-inch  bar histogram,
# with the bars colored darkish gray.
#
# command line variables
POLY=$1
GRID=$2
# get prefix
PREF="`echo $POLY | sed \"s/\(.*\)poly.xy/\1/\"`"
infofile=$PREF.info
# get range
grdinfo $GRID > infofile
RANGE="`grep Command infofile | sed \"s/.*-R\(.*\) -I.*/\1/\"`"
# make and apply the mask
maskfile=$PREF.mask
grdmask -G$maskfile -I0.25c -R$RANGE -V -N0/0/NaN $POLY
postmath=$PREF.postmath
grdmath -V $maskfile $GRID AND = $postmath
# transform grid to histogram format
basexyz=$PREF.basexyz
grd2xyz -V $postmath > $basexyz
ready=$PREF.ready
ready=wfnums.xy
awk '{if ($3!=0) print $3}' $basexyz > $ready
# print the line file
linefile=${PREF}poly.ps
psxy -R$RANGE $POLY -P -JQ-93/12i > $linefile
# build the histogram
histfile=${PREF}hist.ps
outfile=${PREF}hist.info
minmax $ready > $infofile
topval="`grep $ready $infofile | sed \"s/.*<\(.*\)\/.*/\1/\"`"
botval="`grep $ready $infofile | sed \"s/.*\/\(.*\)>.*/\1/\"`"
pshistogram $ready -JX24i -W1 -Z1 -Io > $outfile
valfile=${PREF}hist.val
scratch=${PREF}hist.scr
awk '{print $2}' $outfile > $valfile
minmax $valfile > $scratch
maxval="`grep $valfile $scratch | sed \"s/.*\/\(.*\)>.*/\1/\"`"
minval=0
values=$topval/$botval/$minval/$maxval
pshistogram $ready -JX24i -W1 -P -C -V -Z1 -R$values -Ba10f1/a1f0.5 -G125/125/125 > $histfile
echo "Process completed"
echo "Files created:"
echo $linefile
echo $histfile
echo $outfile
# end of program

User avatar
Void Main
Site Admin
Site Admin
Posts: 5712
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Thu Aug 04, 2005 9:50 pm

I used to do somewhat related work. I used to work in a weather applications shop for the Air Force. Did a lot of work with FORTRAN and SAS on mainframes, PV-WAVE, ARCINFO, SAS and C on IBM RS6000 servers (IBM AIX UNIX) and Linux boxen. We shared a lot of data with NOAA and had a lot of ties with various universities.

Post Reply