Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Function call 3

Status
Not open for further replies.

frangac

Technical User
Feb 8, 2004
163
ZA
Hi PHV,Futurelet or All

How can I call a function from the example given below.
T_S is the unix timestamp (eg 073810000 ,1073810002..).

What I would like to do is whenever the variable T_S is assigned, I would pass it to the function, which inturn convert it to date format (function Time_S )and then printf out.

Time_S(){
echo "0d$1=Y"|adb |sed -e 's/://g'| awk '
BEGIN{OFS=""}
{$2=(index("JanFebMarAprMayJunJulAugSepOctNovDec",$2)-1)/3+1
if($2<10)$2="0"$2
if($3<10)$3="0"$3
print
}'
}

cat FILE | awk '{for (e=1;e<=NF;e++){if (match($e,"CHRIS")){if($82!="V"){st=$85}{if($154=="M"){T_S=$155}{printf "%s %15.f",st,T_S}}}}'

Many Thanks
Chris
 
You can do something like this :
[tt]T_S=$(awk '{for (e=1;e<=NF;e++){if (match($e,"CHRIS")){if($82!="V"){st=$85}{if($154=="M"){T_S=$155}{printf "%s %15.f",st,T_S}}}}' FILE)
ts=$(Time_S $T_S)
[/tt]

Jean Pierre.
 
Hi aigles,

Thanks for the reply, but what I am looking for is when a printf statement is requested {printf "%s %15.f",st,T_S}}}}, the T_S variable is already converted.

Many Thanks
Chris
 
You can try something like this :

Create script file TIME_S with execute perms, instead of a function :

[tt]# --- TIME_S
echo "0d$1=Y" | adb | awk '
BEGIN{
OFS = ""
}
{
gsub(/:/,"");
$2 = (index("JanFebMarAprMayJunJulAugSepOctNovDec",$2)-1)/3+1
if ($2 < 10) $2 = "0" $2
if ($3 < 10) $3 = "0" $3
print
}'
# --- End of file[/tt]

Execute this script file from awk :

[tt]awk '
function Time_S(ut ,d) {
"Time_S" | getline d
close("Time_S")
return d
}
{
for (e=1;e<=NF;e++){
if (match($e,"CHRIS")) {
if ($82!="V") st=$85
if ($154=="M") T_S=Time_S($155)
printf "%s %s",st,T_S
}
}
}' FILE
[/tt]

Jean Pierre.
 
Let's do it entirely in Awk:
[tt]
BEGIN{
hoursecs=60*60; daysecs=24*hoursecs
plainyear = 365*daysecs
print ts2date(1080145459)
print ts2date(1007900000)
}

function ts2date(ts, secs,year,month,day,hour,min,d)
{ ## Adjust for your timezone!!
ts += 2*hoursecs
for (i=1970; ;i++)
{ secs = secs_in_year( i )
if ( ts >= secs )
ts -= secs
else
break
}
year = i
s = "31,28,31,30,30,31,31,30,31,30,31"
split(s,months,",")
if (is_leap(year)) months[2]=29
for (i=1; i<13; i++)
{ secs=months*daysecs
if ( ts >= secs )
ts -= secs
else
break
}
month = (13==i) ? 12 : i
day=int(ts/daysecs); ts -= day*daysecs; day++
hour=int(ts/hoursecs); ts -= hour*hoursecs
min=int(ts/60); ts -= min*60
d=sprintf( "%s/%02d/%02d/%02d:%02d:%02d",
year,month,day,hour,min,ts)
return d
}
function secs_in_year( y )
{ if ( is_leap(y) )
return plainyear + daysecs
else
return plainyear
}
function is_leap( y )
{ if ( (y % 4) || !(y%100) && (y%400) )
return 0
return 1
}
[/tt]

 
Change
[tt]
function ts2date(ts, secs,year,month,day,hour,min,d)
[/tt]
to
[tt]
function ts2date(ts,
secs,i,year,s,months,month,day,hour,min,d)
[/tt]
For safety's sake, we don't want to change any global variables.
 
A bug. In the previous version, I left out one of the months from the list of days in each month.
I hope this is correct:
[tt]
BEGIN{
hoursFromGMT = 2 ## For your timezone.
hoursecs=60*60; daysecs=24*hoursecs
plainyear = 365*daysecs
print ts2date(1080145459)
print ts2date(1007900000)
}

function ts2date(ts,
secs,i,year,s,months,month,day,hour,min,d)
{ ## Adjust for your timezone!!
ts += hoursFromGMT * hoursecs
for (i=1970; ;i++)
{ secs = secs_in_year( i )
if ( ts >= secs )
ts -= secs
else
break
}
year = i
s = "31,28,31,30,31,30,31,31,30,31,30,31"
split(s,months,",")
if (is_leap(year)) months[2]=29
for (i=1; i<12; i++)
{ secs=months*daysecs
if ( ts >= secs )
ts -= secs
else
break
}
month = i
day=int(ts/daysecs); ts -= day*daysecs; day++
hour=int(ts/hoursecs); ts -= hour*hoursecs
min=int(ts/60); ts -= min*60
d=sprintf( "%s/%02d/%02d/%02d:%02d:%02d",
year,month,day,hour,min,ts)
return d
}
function secs_in_year( y )
{ if ( is_leap(y) )
return plainyear + daysecs
return plainyear
}
function is_leap( y )
{ if ( (y % 4) || !(y%100) && (y%400) )
return 0
return 1
}
[/tt]

 
frangac, do all the stuff in awk.
Something like this:
Code:
awk '
function Time_S(ut   ,cmd,buf,a){
 cmd="echo '0d"ut"=Y'|adb|sed -n 's!^[ \t]*!!;s!:!!gp'"
 cmd|getline buf;close(cmd);split(buf,a," ")
 a[2]=(index("JanFebMarAprMayJunJulAugSepOctNovDec",a[2])+2)/3
 return sprintf("%04d%02d%02d%06d",a[1],a[2],a[3],a[4])
}
/CHRIS/{
 if($82!="V" && $154=="M")
  printf "%s %15.f\n",$85,[b]Time_S($155)[/b]
}' FILE
As your awk script is difficult to understand, I show you a variation for example purpose.

Hope This Help, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884
 
Hi Aigles,Futurelet,PHV

Many Thanks for the responce. Futurelet, your script will come in hand (great stuff)

PHV,Aigles,
Thanks Once Agian

My question is, why can I not call a function in my printf statement as show in my first mail for eg
{for (e=1;e<=NF;e++){if (match($e,".[d][v,s,f][0,2][1,9,3].")){if($82!="V"){st=$85}{if($82=="V"){st=""}{if($154=="M"){T_S=$155}{if($155=="M"
){T_S=$156}{printf "%s %15.f %15s %5s %8s %18s %s %s %s %10s %5s\n",$25,Time_S T_S),$58,$68,$70,$61,$82,$75,st,$79,$e;next}

What I am trying to get at is to to assign variables and when the T_S variable is assigned it must get coverted by calling the function and the output to a printf statement.
Is my function Time_S incorrect ?????

If you call the function on its own (separate line), as giving by my first mail, the result appears. When I run it within awk it does not reconige it. Why???????


Hope this is of help

Thanks
Chris
 
Because your function is a shell function, not an awk one.

Hope This Help, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884
 
Hi PHV,

If I run your script I get an error message (see below)

+ cat MM_Cor_match.txt
+ awk
function Time_S(ut ,cmd,buf,a){
cmd="echo 0dut=Y|adb|sed -e s/://g"
cmd|getline buf;close(cmd);split(buf,a," ")
a[2]=(index("JanFebMarAprMayJunJulAugSepOctNovDec",a[2])+2)/3
return sprintf("%04d%02d%02d%06d",a[1],a[2],a[3],a[4])
}{if($0~/^<AT/){getline;next;getline;next;getline;next;}
}
/^S7 A/{
printf "\n%s %s",sep,$0;sep="\n";next}{printf " %s ",$0
+ cut -b1-490,500-550,680-800
+ awk {for (e=1;e<=NF;e++){
if (match($e,".[d][v,s,f][0,2][1,9,3]."))
{
if($82!="V"){st=$85}{if($82=="V"){st=""}{if($154=="M"){T_S=$155}{if($155=="M"){T_S=$156}{printf "%s %15.f %15s %5s %8s %18s %s %s %s %10s %5s\n",$25,Time_S ($T_S), $58,$68,$70,$61,$82,$75,st,$79,$e;next}
}
}
}
}else {
if($e~/.ss09/){
if(match($37,"BlockCall|LRS")
){{da=$60}{bnum=$63}{du=$73}{pci=$78}{id=$82}
}else{
{
bnum=$62}{da=$59}{du=$72}{pci=$77}{id=$81}{st=$84
}
}
{
printf "%s %15s %10s%10s %5s %s %10s %s\n",$25,da,bnum,du,st,pci,id,$e;next
}
}
}
}
}
awk: Function Time_S is not defined.
The input line number is 1.
The source line number is 1.


What does this mean?

Thanks
Chris
 
You must define the Time_S function in the awk script which use it.

Don't prefix the T_S variable with $ :
[tt]Time_S(T_S)[/tt]

Jean Pierre.
 
Aigles,

According to PHV script is that not defined in the awk script or am I missing the point.


+ cat MM_Cor_match.txt
+ awk
function Time_S(ut ,cmd,buf,a){
cmd="echo 0dut=Y|adb|sed -e s/://g"
cmd|getline buf;close(cmd);split(buf,a," ")
a[2]=(index("JanFebMarAprMayJunJulAugSepOctNovDec",a[2])+2)/3
return sprintf("%04d%02d%02d%06d",a[1],a[2],a[3],a[4])

}{if($0~/^<AT/){getline;next;getline;next;getline;next;}
}

Thanks
Chris
 
frangac, please post your script, not the listing produced by set -x.
Anyway, some notes:
1)printf "\n%s %s",sep,$0;sep="\n";next}{printf " %s ",$0
+ cut -b1-490,500-550,680-800
+ awk {for (e=1;e<=NF;e++){

if (match($e,".[d][v,s,f][0,2][1,9,3]."))

Why have we shell execution trace inside an supposed monolithic awk program ?
2)}{if($0~/^<AT/){getline;next;getline;next;getline;next;}
The next statement break out the processing of the current record, so any code after it is ignored

Hope This Help, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884
 
Hi PHV,

The Script is as follows

cat MM_Cor_match.txt |awk '
function Time_S(ut ,cmd,buf,a){
cmd="echo '0d"ut"=Y'|adb|sed -e 's/://g'"
cmd|getline buf;close(cmd);split(buf,a," ")
a[2]=(index("JanFebMarAprMayJunJulAugSepOctNovDec",a[2])+2)/3
return sprintf("%04d%02d%02d%06d",a[1],a[2],a[3],a[4])
}{if($0~/^<AT/){getline;next;getline;next;getline;next;}}/^S7 A/{printf "\n%s %s",sep,$0;sep="\n";next}
{printf " %s ",$0}' |cut -b1-490,500-550,680-800 | awk '{
for (e=1;e<=NF;e++)
{
if (match($e,".[d][v,s,f][0,2][1,9,3].")
)
{
if($82!="V"){st=$85}{if($82=="V"){st=""}{if($154=="M"){T_S=$155}{if($155=="M"){T_S=$156}
{
printf "%s %15.f %15s %5s %8s %18s %s %s %s %10s %5s\n",$25,Time_S
(T_S),$58,$68,$70,$61,$82,$75,st,$79,$e;next
}
}
}
}
}else {
if($e~/.ss09/){if(match($37,"BlockCall|LRS")){{da=$60}{bnum=$63}{du=$73}{pci=$78}{id=$82}}else{{bnum=$62}{da=$59
}{du=$72}{pci=$77}{id=$81}{st=$84}}{printf "%s %15s %10s%10s %5s %s %10s %s\n",$25,da,bnum,du,st,pci,id,$e;next
}}}}}'

A sample of one record after running the above.
(These field differ to each any every record)

<AT 1.1 LV 1.1 NT 3.4.0.0 >Q 3 CDR b J 101 C
S7 A 1 O D 1 D 0 D 0 D 0 D 0 D 0 D 0 D 0 D 128 A 10 0113161181 A 10 011316EEEE D 0 D 0 D 0 A 0 M 1073830528 0 D 2004 D 1 D 11 D 16 D 15 D 28 D 0 D 1 A 14 20040111161528 A 10 0860007249 A 10 086000EEEE A 0 D 18 D 7201 D -1 A 1 B D 1 K 0 A 1 R A 1 M A 1 a A 1 A 1 A 1 A 1 A 0 D -1 D -1 A 2 31 D -1 D -1 D -1 A 0 A 0 A 0 G 0 C SS A 0 A 0 D -1 D -1 D -1 D -1 D -1 D -1 A 0 A 0 A 16 0001755420040111 D 113354 D 2 D 17554 A 4 df23 A 7
read:02 M 1073823327 0 D 2004 D 1 D 11 D 14 D 15 D 27 D 0 D 1 C S A 16 075993650749177E C S4 C S0 A 0 D 0 D 0 D 0 D 0 D 0 D 0 D 0 D 0 D 0 D 0 D 0 D 0 D 0 D 0 D 0 A 44 read:02.df23.0000115.00017554.20040111204003 1 R 3 CDR b
J 101 g A 25 Record_version_SSP_IAC_ST W C g A 19 Record_type_SSP_IAC W A g A 13 Info_flag_ANS W D g A 14 Info_fl ag_ADDA W D g A 14 Info_flag_ADDD W D g A 14 Info_flag_ADDI W D g A 14 Info_flag_ADDU W D g A 18 Info_flag_Reserv ed W D g A 13 info_flag_DDO W D g A 14 Info_flag_ISDN W D g A 9 Info_flag W D g A 16 A_number_CLI_SSP W A g A
23 A_number_CLI_SSP_masked W A g A 19 Billed_party_coding W D g A 21 Billed_party_type_SSP W D g A 24 Billed_party_coding_type W D g A 19 Billed_party_id_SSP W A g A 15 Disconnect_date W M g A 22 Disconnect_Date_Time_Y W D g A 22 Disconnect_Date_Time_M W D g A 22 Disconnect_Date_Time_D W D g A 22 Disconnect_Date_Time_H W D g A 24 Disconnect_Dat
e_Time_MIN W D g A 24 Disconnect_Date_Time_SEC W D g A 27 Disconnect_Date_Time_MILSEC W D g A 24 Disconnect_Date_Time _DOW W D g A 20 Disconnect_date_time W A g A 18 Dialled_digits_SSP W A g A 25 Dialled_digits_SSP_masked W A g A 2
3 Translated_B_number_SSP W A g A 17 Call_charge_units W D g A 13 Call_duration W D g A 29 Duration_before_answer_IAC
_ST W D g A 23 Partial_call_indication W A g A 17 Record_seq_number W D g A 28 Connection_id_number_SSP_IAC W K g
A 11 Status_code W A g A 17 Error_indication1 W A g A 17 Error_indication2 W A g A 17 Error_indication3 W A g A 17 Error_indication4 W A g A 17 Error_indication5 W A g A 17 Error_indication6 W A g A 16 Error_indication W A g A 16 Calculated_units W D g A 19 Calculated_duration W D g A 17 Bearer_capability W A g A 14 IN_service_SSP W D g


The reason for "cut -b1-490,500-550,680-800" due to the fact that awk complains awk: Input line S7 A 1 O D 1 D 0 cannot be longer than 3,000 bytes and for "{if($0~/^<AT/){getline;next;getline;next;getline;next;}, this line is not required.

I have tried to simplify my explanation and hope that this is Comprehencable.
If you have a better solution, I am eager to learn.

Many Thanks
Chris


 
In fact you have two awk programs.
The Time_S function is defined in the 1st and called in the 2nd.
I don't understand why you can't do all the process in a single awk program.
The 3000 char length limitation is for input record, not string variable.

Hope This Help, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884
 
The two awk scripts are in blue.

[tt]cat MM_Cor_match.txt | awk '
function Time_S(ut ,cmd,buf,a){
cmd = "echo '0d"ut"=Y'|adb|sed -e 's/://g'"
cmd|getline buf;
close(cmd);
split(buf,a," ")
a[2]=(index("JanFebMarAprMayJunJulAugSepOctNovDec",a[2])+2)/3
return sprintf("%04d%02d%02d%06d",a[1],a[2],a[3],a[4])
}
{
if ($0~/^<AT/) {
getline; next;
getline; next;
getline; next;
}
}
/^S7 A/ {
printf "\n%s %s",sep,$0;sep="\n";
next
}
{
printf " %s ",$0
} '
| cut -b1-490,500-550,680-800 | awk '
{
for (e=1;e<=NF;e++) {
if (match($e,".[d][v,s,f][0,2][1,9,3].")) {
if ($82!="V"){
st=$85
}
{
if ($82=="V") {
st=""
}
{
if ($154=="M") {
T_S=$155
}
{
if ($155=="M") {
T_S=$156
}
{
printf "%s %15.f %15s %5s %8s %18s %s %s %s %10s %5s\n",$25,Time_S(T_S),$58,$68,$70,$61,$82,$75,st,$79,$e;
next
}
}
}
}
} else {
if ($e~/.ss09/) {
if (match($37,"BlockCall|LRS")) {
{
da=$60
}
{
bnum=$63
}
{
du=$73
}
{
pci=$78
}
{
id=$82
}
} else {
{
bnum=$62
}
{
da=$59
}
{
du=$72
}
{
pci=$77
}
{
id=$81
}
{
st=$84
}
}
{
printf "%s %15s %10s%10s %5s %s %10s %s\n",$25,da,bnum,du,st,pci,id,$e;
next
}
}
}
}
}'
[/tt]


Don't enclose every statement between brackets.
Change your script formatting, the script will be more readable.


Jean Pierre.
 
Hi Aigles,PHV,

Thanks

I did place it into the second awk and got an error mesg
as awk: A next statement cannot be used inside a function

PHV,

I like you statment "why you can't do all the process in a single awk program", like I said I am willing to learn

Thanks Once Again.
Chris
 
The Time_S function doesn't contain a next statement.
Are you sure that you move the function at the right place ?
You must have something like this :
[tt]
cut -b1-490,500-550,680-800 | awk '
function Time_S(ut ,cmd,buf,a){
cmd = "echo '0d"ut"=Y'|adb|sed -e 's/://g'"
cmd|getline buf;
close(cmd);
split(buf,a," ")
a[2]=(index("JanFebMarAprMayJunJulAugSepOctNovDec",a[2])+2)/3
return sprintf("%04d%02d%02d%06d",a[1],a[2],a[3],a[4])
}
{
for (e=1;e<=NF;e++) {
if (match($e,".[d][v,s,f][0,2][1,9,3].")) {
[/tt]

Jean Pierre.
 
Hi PHV,Aigles

When I run the script with calling the function printf "%.f\n",Time_S($155) ), the result is "0", but if use printf "%.f\n",$155, the timestamp is displayed correctly.
Why whould it give me a result of "0", when I know that the function is requested.

cat MM_Cor_match.txt | awk '
{
if ($0~/^<AT/) {
getline; next;
getline; next;
getline; next;
}
}
/^S7 A/ {
printf "\n%s %s",sep,$0;sep="\n";
next
}
{
printf " %s ",$0
} ' | cut -b1-490,500-550,680-800 | awk '
function Time_S(ut ,cmd,buf,a){
cmd = "echo '0d"ut"=Y'|adb|sed -e 's/://g'"
cmd|getline buf;
close(cmd);
split(buf,a," ")
a[2]=(index("JanFebMarAprMayJunJulAugSepOctNovDec",a[2])+2)/3
return sprintf("%04d%02d%02d%06d",a[1],a[2],a[3],a[4])
}
{printf "%.f\n",Time_S($155)}'


Thanks
Chris
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top