Computing.Net > Forums > Unix > AWk help

AWk help

Reply to Message Icon

Original Message
Name: xaiver
Date: June 28, 2005 at 00:02:47 Pacific
Subject: AWk help
OS: HP-UNIX
CPU/Ram: -
Comment:

i need to write an awk script to produce a report in table form.

the data is in a file similar to below
H16 M1-INV 199
M32 M1-INV 5

N32 M1-CSC 46
N64 M1-CSC 49
3G64 M1-CSC 191
3G64 M1-DMY 53
HS32 M1-INV 145
3G128 M1-CSC 53
3G128 CCHQ9901 150

I need to produce a table with the 1st column as the top row and the 2nd column as the 1st column of the table. the 3rd column is my data and slotted in the table based on the 1st column and 2nd column.

Appreciate if anyone can help

Thanks



Report Offensive Message For Removal


Response Number 1
Name: gurubit
Date: June 28, 2005 at 02:32:50 Pacific
Subject: AWk help
Reply: (edit)

Give the expected output.
This will help me and others to help you.


Report Offensive Follow Up For Removal

Response Number 2
Name: xaiver
Date: June 28, 2005 at 02:57:06 Pacific
Subject: AWk help
Reply: (edit)

sample output will be as below.

Thanks

H16 M32 N32 N64
M1-INV 199 5
M1-CSC 46 49


Report Offensive Follow Up For Removal

Response Number 3
Name: xaiver
Date: June 28, 2005 at 03:01:39 Pacific
Subject: AWk help
Reply: (edit)

the formating is a bit out after psoting.
but it is like a table form where 199 is under H16 and beside m1_INV
46 under N32 and beside M1_CSC



Report Offensive Follow Up For Removal

Response Number 4
Name: gurubit
Date: June 28, 2005 at 04:06:28 Pacific
Subject: AWk help
Reply: (edit)

Use the script below:

#!/bin/ksh
col1=`awk '{print $1}' test.txt`
echo " " $col1 > test.out
awk '{print $2 " " $3}' test.txt >> test.out

where

1) test.txt : the file containing the text.
2) test.out : The output file.

This will have some problem in formatting which on using printf can be changed but again if the col1 length increases, then the formatting will be lost.
You can try playing with formatting.

Hope it helps,
Rajesh


Report Offensive Follow Up For Removal

Response Number 5
Name: Jim Boothe
Date: June 28, 2005 at 06:38:23 Pacific
Subject: AWk help
Reply: (edit)

I think each columnar heading needs to appear only once. The output below is based on the sample data posted, except that I omitted the last (3G128) column due to width constraints here.

If you were to copy/paste this output into a proportional spaced forum, the columns would be aligned, but in this forum, spaces are narrower than other characters.

       H16 M32 N32 N64 3G64 HS32
M1-INV 199
M1-INV       5
M1-CSC          46
M1-CSC              49
M1-CSC                  191
M1-DMY                   53
M1-INV                       145

OK, I did the hard part.
Now all we need is a solution. :-D


Report Offensive Follow Up For Removal


Response Number 6
Name: Jim Boothe
Date: June 28, 2005 at 08:47:02 Pacific
Subject: AWk help
Reply: (edit)

This solution assumes that the input file is already sorted in the desired order.  It will be processed/printed in that order, as regards both the horizontal headings and the vertical columns.

Maximum width for table column 1 is currently set for 9.  To adjust this, change the c1w value.

Space allocated for each column across the page is 7.  To adjust this, change the three 7's to something else, but keep them all the same.

Since your data is numeric, I right-justified both the columnar headings and the data columns.

awk 'BEGIN \
{c1w=9
 col1indent=substr("            ",1,c1w)
 while ((getline < "test.txt") > 0)
  if ($1 in coltable)
     x=1
  else
    {printf "%s%7s",col1indent,$1
     col1indent=""
     colnbr++
     coltable[$1] = colnbr}
 printf "\n"
}
{indents=coltable[$1]-1
 spaces=indents*7
 printf "%-" c1w "s%" spaces "s%7s\n",$2,"",$3
}' test.txt


Report Offensive Follow Up For Removal

Response Number 7
Name: Jim Boothe
Date: June 28, 2005 at 09:07:22 Pacific
Subject: AWk help
Reply: (edit)

OK, version 2 has a slight refinement on allowing for column 1 width when constructing the column headings with printf statement.

awk 'BEGIN \
{c1w=9
 c1indent=c1w
 while ((getline < "test.txt") > 0)
  if ($1 in coltable)
     x=1
  else
    {printf "%" c1indent "s%7s","",$1
     c1indent=0
     colnbr++
     coltable[$1] = colnbr}
 printf "\n"
}
{indents=coltable[$1]-1
 spaces=indents*7
 printf "%-" c1w "s%" spaces "s%7s\n",$2,"",$3
}' test.txt


Report Offensive Follow Up For Removal

Response Number 8
Name: xaiver
Date: June 28, 2005 at 19:19:06 Pacific
Subject: AWk help
Reply: (edit)

Hi both,

Thanks for the help.

Jim, ur solution is great.
however need a bit more help here.

for eg.
M1-CSC is seperated into different rows.
I need one row just for M1-CSC and the various numbers all in 1 line which is linked to M1-CSC like 5 under M32, 46 under N32 but all on the same horizontal row.

I will try to work on ur solution and see if I can tweak it to get it to work i needed.

Thanks a lot again


Report Offensive Follow Up For Removal

Response Number 9
Name: Jim Boothe
Date: June 29, 2005 at 08:16:55 Pacific
Subject: AWk help
Reply: (edit)

Yes, I understand. Working on it now ...


Report Offensive Follow Up For Removal

Response Number 10
Name: Jim Boothe
Date: June 29, 2005 at 12:32:16 Pacific
Subject: AWk help
Reply: (edit)

I call this an xy report where x represents the horizontal columnar headings and y represents the vertical labels.

The solution below does an initial sort on the input file, which is then piped into awk pass #1.  Note that this first sort is completely optional, and its sole purpose is to control the sequencing of the x columnar headings.  The sort can be eliminated (change awk pass #1 to read the input file directly), or the sort could be fancied up to get the desired order of x.

Like the prior solution, the data is passed twice, but while the prior solution passed it once in BEGIN processing and once in main processing, this solution uses two separate awk's with a sort in between.

awk pass #1 assigns numbers to the x values as encountered (based on either the non-sorted or sorted file), and rewrites the input file and includes these numerical column assignments for sorting purposes.  The intermediate file is then sorted primary on y and secondary on numerical x.  Controlling the secondary x sort on a generated value allows you to have/sort the file in any desired order for controlling the order of the x columns.

This solution prints multiple y entries all on one line, and does so by constructing the y line by doing multiple printf commands without closing the line out, thus I require the multiple y entries to arrive in the order that they will be printed across the line horizontally.

awk pass #1 also constructs the column heading for the report as it discovers each unique x column.  This heading is written at the end of the pass, and the blanks at the beginning of this heading line just happen to serve the purpose of making this line sort to the front.

awk pass #2 implements control-break logic on the y lines.  At the start of a new y group, the previous y line is closed out, and construction of a new line begins by printing the y label.  Then one by one, each data value is printed across the line.  I print it under the proper column by calculating the proper amount of space padding.

The width of a y column is now hard-coded at 9 characters.  To change this, change the number of spaces assigned to rptheading, and also change the "%-9s" respectively.

infile=xyreport.in
workfile=/tmp/xyrpt.$$

sort $infile |
awk 'BEGIN \
{rptheading="         "}
{if ($1 in colheadings)
    colnbr=colheadings[$1]
 else
   {colseq++
    colnbr=colseq
    rptheading=rptheading sprintf("%7s",$1)
    colheadings[$1]=colnbr}
 print $2,colnbr,$1,$3
}
END {print rptheading}
' | sort > $workfile

awk 'BEGIN \
{getline
 print # (rptheading)
}
{if (holdw1!=$1)
   {if (holdw1!="")
       printf "\n"
    holdw1=$1
    printf "%-9s",$1
    currcol=0}
 skipcolumns=$2-currcol-1
 spaces=skipcolumns*7
 printf "%" spaces "s%7s","",$4
 currcol=$2
}
END {printf "\n"}' $workfile

rm $workfile


Report Offensive Follow Up For Removal

Response Number 11
Name: xaiver
Date: July 13, 2005 at 00:52:28 Pacific
Subject: AWk help
Reply: (edit)

thx a lot!
it works like wonders!

I will study and understand it!



Report Offensive Follow Up For Removal

Response Number 12
Name: xaiver
Date: July 21, 2005 at 19:45:22 Pacific
Subject: AWk help
Reply: (edit)

After some testing, realised there is a bug. if my x-row (header) has more than 9 entries, colnbr will be 10,11 and so on.

on sorting it will be sorted in 10,11,2,3,4 and this messes up the table.

tried unsuccessfully to append a 0 to the single digit (eg,02,03) which will sort things up correctly.

Any way to overcome this ?

Thanks


Report Offensive Follow Up For Removal






Use following form to reply to current message:

   Name: From My Computing.Net Settings
 E-Mail: From My Computing.Net Settings

Subject: AWk help

Comments:

 


  Homepage URL (*): 
Homepage Title (*): 
         Image URL: 
 
Data Recovery Software