calling functions in awk



I found a script online that compares two dates and gives output as
number of days in between both the dates. It works perftecly fine.
Here is the script I found online

---------------------------------------------------------------------------------

# days-between.sh: Number of days between two dates.
# Usage: ./days-between.sh [M]M/[D]D/YYYY [M]M/[D]D/YYYY
#
# Note: Script modified to account for changes in Bash, v. 2.05b +,
#+ that closed the loophole permitting large negative
#+ integer return values.

ARGS=2 # Two command line parameters expected.
E_PARAM_ERR=65 # Param error.

REFYR=1600 # Reference year.
CENTURY=100
DIY=365
ADJ_DIY=367 # Adjusted for leap year + fraction.
MIY=12
DIM=31
LEAPCYCLE=4

MAXRETVAL=255 # Largest permissible
#+ positive return value from a function.

diff= # Declare global variable for date difference.
value= # Declare global variable for absolute value.
day= # Declare globals for day, month, year.
month=
year=


Param_Error () # Command line parameters wrong.
{
echo "Usage: `basename $0` [M]M/[D]D/YYYY [M]M/[D]D/YYYY"
echo " (date must be after 1/3/1600)"
exit $E_PARAM_ERR
}


Parse_Date () # Parse date from command line params.
{
month=${1%%/**}
dm=${1%/**} # Day and month.
day=${dm#*/}
let "year = `basename $1`" # Not a filename, but works just the
same.
}


check_date () # Checks for invalid date(s) passed.
{
[ "$day" -gt "$DIM" ] || [ "$month" -gt "$MIY" ] ||
[ "$year" -lt "$REFYR" ] && Param_Error
# Exit script on bad value(s).
# Uses or-list / and-list.
#
# Exercise: Implement more rigorous date checking.
}


strip_leading_zero () # Better to strip possible leading zero(s)
{ #+ from day and/or month
return ${1#0} #+ since otherwise Bash will interpret them
} #+ as octal values (POSIX.2, sect 2.9.2.1).


day_index () # Gauss' Formula:
{ # Days from March 1, 1600 to date passed as
param.
# ^^^^^^^^^^^^^
day=$1
month=$2
year=$3

let "month = $month - 2"
if [ "$month" -le 0 ]
then
let "month += 12"
let "year -= 1"
fi

let "year -= $REFYR"
let "indexyr = $year / $CENTURY"


let "Days = $DIY*$year + $year/$LEAPCYCLE - $indexyr \
+ $indexyr/$LEAPCYCLE + $ADJ_DIY*$month/$MIY + $day -
$DIM"
# For an in-depth explanation of this algorithm, see
#+ http://weblogs.asp.net/pgreborio/archive/2005/01/06/347968.aspx


echo $Days

}


calculate_difference () # Difference between two day
indices.
{
let "diff = $1 - $2" # Global variable.
}


abs () # Absolute value
{ # Uses global "value" variable.
if [ "$1" -lt 0 ] # If negative
then #+ then
let "value = 0 - $1" #+ change sign,
else #+ else
let "value = $1" #+ leave it alone.
fi
}



if [ $# -ne "$ARGS" ] # Require two command line params.
then
Param_Error
fi

Parse_Date $1
check_date $day $month $year # See if valid date.

strip_leading_zero $day # Remove any leading zeroes
day=$? #+ on day and/or month.
strip_leading_zero $month
month=$?

let "date1 = `day_index $day $month $year`"


Parse_Date $2
check_date $day $month $year

strip_leading_zero $day
day=$?
strip_leading_zero $month
month=$?

date2=$(day_index $day $month $year) # Command substitution.


calculate_difference $date1 $date2

abs $diff # Make sure it's positive.
diff=$value

echo $diff

exit 0

# Compare this script with
#+ the implementation of Gauss' Formula in a C program at:
#+ http://buschencrew.hypermart.net/software/datedif
-------------------------------------------------------------------------------------------------------------------------

Now I want to use about script in my awk program. I tried to do that
by creating it as a shell function and then call it from with in awk
like this.

DIFF_DATE='
function diff_date {
# ABOVE MENTIONED SCRIPT IS COPIED HERE
} #End of shell function diff_DATE
' #End of DIFF_DATE

export DIFF_DATE

awk 'BEGIN{
#some awk business

date1=1/1/2007
date2=2/2/2008

system(ENVIRON["DIFF_DATE"]"diff_date" "date1" "date2)

#more awk stuff
}'

But this does not work. Then I tried the following


function diff_date {
# ABOVE MENTIONED SCRIPT IS COPIED HERE
} #End of shell function diff_DATE

CALL='
function call_diff_date {
diff_date $1 $2
} # End of function.
' #End of CALL
export DIFF_DATE

awk 'BEGIN{
#some awk business

date1=1/1/2007
date2=2/2/2008

system(ENVIRON["DIFF_DATE"]"diff_date" "date1" "date2)


But this gives me an error that date_diff not found.

In the above script if I call call_diff_date function with in shell
script (not in awk) then it works fine. like this

function diff_date {
# ABOVE MENTIONED SCRIPT IS COPIED HERE
} #End of shell function diff_DATE


function call_diff_date {
diff_date $1 $2
} # End of function.

call_diff_date

above script works fine. but it gives errors with I try to call it
from awk. Here I would like to mention that the way of calling shell
functions mentioned above works fine. But in case of nested shell
functions it is a problem.

Any ideas why?

Reargds,
Rachit Bhatia.

.



Relevant Pages

  • Re: How to rewrite with awk?
    ... > I'm unfamiliar with tools such as sed & awk. ... Extract the string that matches a RE. ... This script will not only expand all the lines that say "include ... file) and not resetting ARGV(the tmp file), it then lets awk do any ...
    (comp.unix.shell)
  • Re: for loop (?)
    ... you should use awk variables in awk scripts instead ... >>of shell variables to avoid problems when those shell variables include ... I doubt if I've ever written a shell script that's robust ... > extra effort to make the script robust against weird inputs. ...
    (comp.unix.shell)
  • Re: How to remove all .DS_Store files using Terminal?
    ... Great tip, I will add that to my limited Unix arsenal, thanks. ... When I first saw this script, ... into an awk script. ... The conditional expression can be a search string as in /abc/ or a ...
    (comp.sys.mac.system)
  • Re: for loop (?)
    ... you should use awk variables in awk scripts instead ... > of shell variables to avoid problems when those shell variables include ... can handle NUL characters correctly in its input. ... pass these characters to the script in the first place. ...
    (comp.unix.shell)
  • calling shell functions in awk
    ... I found a script online that compares two dates and gives output as ... Now I want to use about script in my awk program. ... by creating it as a shell function and then calling it from with in ... # ABOVE MENTIONED SCRIPT IS COPIED HERE ...
    (comp.lang.awk)