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!

awk.. 2

Status
Not open for further replies.

buccaneers

Programmer
Jun 3, 2004
28
US
Hello Gurus,

I have one question if i may ask.

Using awk/nawk

can one write a report such that one position the output within output file. Here is what i am trying to do. I have following files :-

tbldef containing following lines
Curr_Dt datetime Not Null
Pcr_ID string(15) Not Null
Tran_ID string(15) Not Null
Unts_No integer Not Null
Prcg_ID integer Not Null
Pcr_Nme string(30) Not Null
Wav_Ind string(1) Not Null
Flx_Ind string(1) Not Null
Rt_Cd string(2) Null
St_flag string(1) null

tbldat containing
5/31/2004 1:00:00.000 PM~~999999999 ~~1 ~~10~~25~~Test~~Y~~N~~CC~1
5/31/2004 1:30:50.000 PM~~999999991 ~~4 ~~45~~10~~Test1~~N~~N~~BB~0
5/31/2004 1:35:45.000 PM~~999999292 ~~2 ~~30~~15~~Test2~~N~~Y~~AA~1


I want the output to be written in the format specified as
Curr_Dt : 5/31/2004 1:00:00.000 PM : 5/31/2004 1:30:50.000 PM : 5/31/2004 1:35:45.000 PM
Pcr_ID : 999999999 : 999999991 : 999999292
Tran_ID : 1 : 4 : 2
Unts_No : 10 : 45 : 30
Prcg_ID : 25 : 10 : 15
Pcr_Nme : Test : Test1 : Test2
Wav_Ind : Y : N : N
Flx_Ind : N : N : Y
Rt_Cd : CC : BB : AA
St_flag : 1 : 0 : 1

NOTE :- You may not be able to see the fixed length between the field name and ":" cause of HTML formatiing. Pls copy it to notepad or any test editor for the output that is expected.

Is it possible with awk. If so how ? i have been breaking my head over it to noavail.

TIA
 
Something like this ?
awk '
BEGIN{while((getline<"tbldef")>0)h[++j]=$1;FS="~~"}
{for(i=1;i<NF;++i)d[i","FNR]=$i
d[i++","FNR]=substr($NF,1,length($NF-2))
d[i","FNR]=substr($NF,length($NF))
}
END{for(i=1;i<=j;++i){
printf h
for(r=1;r<=FNR;++r)
printf "\t:"d[i","r]
printf "\n"
}}
' tbldat

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
something like this:

Code:
BEGIN {
  FS="~~"
  split("Curr_Dt Pcr_ID Tran_ID Unts_No Prcg_ID Pcr_Nme Wav_Ind Flx_Ind Rt_Cd St_flag", head, " ");
}

{
  for(i=1; i <= NF; i++)
    arr[i]= (arr[i]) ? arr[i] ":" sprintf("%-30s", $i) : sprintf("%-30s", $i);

  nf=NF
}

END {
  for(i=1; i <= nf; i++)
    printf("%-10s: %s\n", head[i], arr[i]);
}

vlad
+----------------------------+
| #include<disclaimer.h> |
+----------------------------+
 
Thanx a lot PHV and vlad for a quick response. I tested phv's solution and it works for me. I have only changed one thing in the code and that is of using ~~ as the separator instead of :. Also i changed from

printf "\t:"d[i","r]
to
printf ("%-30s~~",d[i","r])

This was to have fixed length output.

Just out of curiosity i have few questions if i may ask to phv. What is the significance of the code
d[i++","FNR]=substr($NF,1,length($NF-2))
d[i","FNR]=substr($NF,length($NF))

i know it is assigning a substring into array d[i,r] but wouldn't this be constant for all throughout the loop and the tbldat would always have 10 as NF for each line. I may be wrong in understanding this hence the question. would appreciate if you can clear my doubt.

Also can we do it the reverse way. from the output

Curr_Dt : 5/31/2004 1:00:00.000 PM : 5/31/2004 1:30:50.000 PM : 5/31/2004 1:35:45.000 PM
Pcr_ID : 999999999 : 999999991 : 999999292

generate the file similar to tbldat with say "~~" as field separator.

Again thanx a lot for your valuable time.

TIA.


 
Just out of curiosity i have few questions if i may ask to phv. What is the significance of the code
d[i++","FNR]=substr($NF,1,length($NF-2))
d[i","FNR]=substr($NF,length($NF))

[tt]5/31/2004 1:00:00.000 PM~~999999999 ~~1 ~~10~~25~~Test~~Y~~N~~CC~1
5/31/2004 1:30:50.000 PM~~999999991 ~~4 ~~45~~10~~Test1~~N~~N~~BB~0
5/31/2004 1:35:45.000 PM~~999999292 ~~2 ~~30~~15~~Test2~~N~~Y~~AA~1[/tt]
The last field is separated from the previous by only one ~
This is why I added this code.

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
my mistake.. it should have been ~~ instead of ~ in the last field.

Anyways is it possible to get from

Curr_Dt ~~5/31/2004 1:00:00.000 PM ~~5/31/2004 1:30:50.000 PM ~~5/31/2004 1:35:45.000 PM ~~
Pcr_ID ~~999999999 ~~999999991 ~~999999292 ~~
Tran_ID ~~1 ~~4 ~~2 ~~
Unts_No ~~10 ~~45 ~~30 ~~
Prcg_ID ~~25 ~~10 ~~15 ~~
Pcr_Nme ~~Test ~~Test1 ~~Test2 ~~
Wav_Ind ~~Y ~~N ~~N ~~
Flx_Ind ~~N ~~N ~~Y ~~
Rt_Cd ~~CC ~~BB ~~AA ~~
St_flag ~~1 ~~0 ~~1 ~~

To
5/31/2004 1:00:00.000 PM~~999999999 ~~1 ~~10~~25~~Test~~Y~~N~~CC~~1
5/31/2004 1:30:50.000 PM~~999999991 ~~4 ~~45~~10~~Test1~~N~~N~~BB~~0
5/31/2004 1:35:45.000 PM~~999999292 ~~2 ~~30~~15~~Test2~~N~~Y~~AA~~1

Assuming that number of fields in input could be variable resulting in one less then that many number of lines in output.

In the above example it has 4 fields in input and i have 3 data lines. but i could have 7 fields resulting in 6 data lines in output.


Sorry for asking this many questions but i am new to awk.

TIA.
 
Typed, not tested, no formatting:
awk -F'~~' '
{for(i=2;i<NF;++i){sub(/ *$/,"",$i);a[NR","i]=$i}}
END{for(i=2;i<NF;++i){
printf "%s",a[1","$i]
for(r=2;r<=NR;++r)printf "~~%s",a[r","$i]
printf "\n"
}}
'

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
Made few changes since awk doesn't recognize "~~" as FS and gives error

awk: syntax error near line 2
awk: illegal statement near line 2

below is changed script.

nawk '
BEGIN {FS="\~\~"}
{for(i=2;i<NF;++i){sub(/ *$/,"",$i);a[NR","i]=$i}}
END{for(i=2;i<NF;++i){
printf "%s",a[1","$i]
for(r=2;r<=NR;++r){
printf "~~%s",a[r","$i]
}
printf "\n"
}}
' tbl1.out

But it doesn't give any output. do u know any way to debug it like say "ksh -x" for korn shell script ?

TIA.
 
Perhaps your awk flavor don't like NF in the END section:
nawk '
BEGIN {FS="\~\~"}
{for(i=2;i<NF;++i){sub(/ *$/,"",$i);a[NR","i]=$i}
nf=NF;nr=NR}
END{for(i=2;i<nf;++i){
printf "%s",a[1","$i]
for(r=2;r<=nr++r){
printf "~~%s",a[r","$i]
}
printf "\n"
}}
' tbl1.out

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
A step ahead from previous state. Now it is printing only

~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~

Here is the nawk code..

nawk '
BEGIN {FS="\~\~"}
{for(i=2;i<NF;++i){sub(/ *$/,"",$i);a[NR","i]=$i}
nf=NF;nr=NR}
END{for(i=2;i<nf;++i){
printf "%s",a[1","$i]
for(r=2;r<=nr;++r){
printf "~~%s",a[r","$i]
}
printf "\n"
}}
' tbl1.out

and here is what is in tbl1.out

Curr_Dt ~~5/31/2004 1:00:00.000 PM ~~5/31/2004 1:30:50.000 PM ~~5/31/2004 1:35:45.000 PM ~~
Pcr_ID ~~999999999 ~~999999991 ~~999999292 ~~
Tran_ID ~~1 ~~4 ~~2 ~~
Unts_No ~~10 ~~45 ~~30 ~~
Prcg_ID ~~25 ~~10 ~~15 ~~
Pcr_Nme ~~Test ~~Test1 ~~Test2 ~~
Wav_Ind ~~Y ~~N ~~N ~~
Flx_Ind ~~N ~~N ~~Y ~~
Rt_Cd ~~CC ~~BB ~~AA ~~
St_flag ~~1 ~~0 ~~1 ~~


Thx a lot for responding.

--TIA
 
Sorry for the typos, my bad.
nawk '
BEGIN {FS="\~\~"}
{for(i=2;i<NF;++i){sub(/ *$/,"",$i);a[NR","i]=$i}
nf=NF;nr=NR}
END{for(i=2;i<nf;++i){
printf "%s",a[1","[highlight]i[/highlight]]
for(r=2;r<=nr;++r){
printf "~~%s",a[r","[highlight]i[/highlight]]
}
printf "\n"
}}
' tbl1.out

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top