Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Formatting
Ok, need some more help formatting another report.  What I'm trying to do
is take a file that looks something similar to the following:

Name: Fred INFO: 1/text/text/text, 2/text/text/text, etc.
Name: Sam INFO: 1/text/text/text, 2/text/text/text, etc.

The fields after 'INFO:' could vary from none to quite a number.  I'd like
to be able to generate a report that would end up looking something like
this:

Name	Info
----	----
Fred	1/text/text/text
2/text/text/text
3/text/text/text
Sam	1/text/text/text
2/text/text/text
3/text/text/text

The problem is I haven't quite been able to puzzle through it using awk.
If someone has a pointer I'd very much appreciate it.  Thanks!

--
Link King
king@kinger.net


Report this thread to moderator Post Follow-up to this message
Old Post
Link King
03-20-04 01:23 AM


Re: Formatting
In article <Pine.LNX.4.44.0402101708220.25758-100000@mogul.kinger.net>,
Link King <king@kinger.net> wrote:

> Ok, need some more help formatting another report.  What I'm trying to do
> is take a file that looks something similar to the following:
>
> Name: Fred INFO: 1/text/text/text, 2/text/text/text, etc.
> Name: Sam INFO: 1/text/text/text, 2/text/text/text, etc.
>
> The fields after 'INFO:' could vary from none to quite a number.  I'd like
> to be able to generate a report that would end up looking something like
> this:
>
> Name	Info
> ----	----
> Fred	1/text/text/text
> 	2/text/text/text
> 	3/text/text/text
> Sam	1/text/text/text
>         2/text/text/text
>         3/text/text/text
>
> The problem is I haven't quite been able to puzzle through it using awk.
> If someone has a pointer I'd very much appreciate it.  Thanks!

I would probably change the ':' and ',' to white space and then just
print the second and fourth field on one line and the rest on following
lines.

--
Robert B. Peirce, Venetia, PA  724-941-6883
bob AT peirce-family.com [Mac]
rbp AT cooksonpeirce.com [Office]


Report this thread to moderator Post Follow-up to this message
Old Post
Robert Peirce
03-20-04 01:23 AM


Re: Formatting
In article <Pine.LNX.4.44.0402101708220.25758-100000@mogul.kinger.net>,
Link King  <king@kinger.net> wrote:

% Name: Fred INFO: 1/text/text/text, 2/text/text/text, etc.
% Name: Sam INFO: 1/text/text/text, 2/text/text/text, etc.

You'll need to either store all the values or make two passes. I suggest
setting

FS = " *(INFO)?: +"

so you'll have

$1 = "Name"
$2 = "Fred"
$3 = "1/text/..."

You can store this in an array, and store the maximum length at the
same time

info[$2] = $3
maxlen = maxlen >= length($2) ? maxlen : length($2)

At the end, you split up the info into another array using split

for (name in info) {
nf = split(info[name], f, /, */)

then print the first piece of information with the name, and the other
pieces of information without the name. You use printf to do the
printing, and specify a width on the first field. If you knew all the
names were going to be less than 10 characters, you could write

printf "%-10s %s\n", "Name", "Info"
printf "%-10s %s\n", "----", "----"
printf "%-10s %s\n", name, f[1]

and so on. You don't know that, but you do know the names will be
less than maxlen characters long, so you can put that into the
format string, either like this:

fmtstring = "%-" maxlen "s %s\n"

printf fmtstring, name, f[1]

or like this

printf "%-*s %s\n", maxlen, name, f[1]

The former is more portable and probably easier to use and faster.

Putting it all together (but not testing it)

BEGIN { FS = " *(INFO)?: +" }
END {
fmtstring = "%-" maxlen "s %s\n"

printf fmtstring, "Name", "Info"
printf fmtstring, "----", "----"

for (name in info) {
nf = split(info[name], f, /, */)
printf fmtstring, name, f[1]
for (i = 2; i <= nf; i++)
printf fmtstring, "", f[i]
}
}

{  info[$2] = $3
l = length($2)
if (maxlen < l)
maxlen = l
}

--

Patrick TJ McPhee
East York  Canada
ptjm@interlog.com

Report this thread to moderator Post Follow-up to this message
Old Post
Patrick TJ McPhee
03-20-04 01:23 AM


Re: Formatting
Patrick,

Thanks for the reply.  It's very helpful.  However, I think I've
oversimplified things a bit and I'm only partially successful in getting
things to format properly.  Here is an actual record from the file I'm
working with:

Host: 10.10.10.10 (xyz.abc.com)       Ports: 53/open/tcp//domain?///, 53/ope
n/udp//domain?///, 25/open/tcp//smtp///

There will be a large number of records similar to this.  What I'd like to
see is something like this per record:

Host				Ports
----				-----
10.10.10.10 (xyz.abc.com)	53/open/tcp//domain
53/open/udp//domain
25/open/tcp//smtp

I'm close with the pointers you've given but not quite there.  Two things
in particular.  One, the hosts/records are not printing out in the order
they appear in the file.  Second, the formatting for the first line is
off.  So, instead of the above it will appear like so:

Host                            Ports
----                            -----
10.10.10.10 (xyz.abc.com)              53/open/tcp//domain
53/open/udp//domain
25/open/tcp//smtp

Or something like that.  Have tried a number of different formatting
options to no avail thus far.  Any additional pointers would be great.

Thanks!

-Link

> In article <Pine.LNX.4.44.0402101708220.25758-100000@mogul.kinger.net>,
> Link King  <king@kinger.net> wrote:
>
> % Name: Fred INFO: 1/text/text/text, 2/text/text/text, etc.
> % Name: Sam INFO: 1/text/text/text, 2/text/text/text, etc.
>
> You'll need to either store all the values or make two passes. I suggest
> setting
>
>  FS = " *(INFO)?: +"
>
> so you'll have
>
>  $1 = "Name"
>  $2 = "Fred"
>  $3 = "1/text/..."
>
> You can store this in an array, and store the maximum length at the
> same time
>
>  info[$2] = $3
>  maxlen = maxlen >= length($2) ? maxlen : length($2)
>
> At the end, you split up the info into another array using split
>
>   for (name in info) {
>      nf = split(info[name], f, /, */)
>
> then print the first piece of information with the name, and the other
> pieces of information without the name. You use printf to do the
> printing, and specify a width on the first field. If you knew all the
> names were going to be less than 10 characters, you could write
>
>   printf "%-10s %s\n", "Name", "Info"
>   printf "%-10s %s\n", "----", "----"
>   printf "%-10s %s\n", name, f[1]
>
> and so on. You don't know that, but you do know the names will be
> less than maxlen characters long, so you can put that into the
> format string, either like this:
>
>   fmtstring = "%-" maxlen "s %s\n"
>
>   printf fmtstring, name, f[1]
>
> or like this
>
>   printf "%-*s %s\n", maxlen, name, f[1]
>
> The former is more portable and probably easier to use and faster.
>
> Putting it all together (but not testing it)
>
>  BEGIN { FS = " *(INFO)?: +" }
>  END {
>     fmtstring = "%-" maxlen "s %s\n"
>
>     printf fmtstring, "Name", "Info"
>     printf fmtstring, "----", "----"
>
>     for (name in info) {
>        nf = split(info[name], f, /, */)
>        printf fmtstring, name, f[1]
>        for (i = 2; i <= nf; i++)
>           printf fmtstring, "", f[i]
>     }
>  }
>
>  {  info[$2] = $3
>      l = length($2)
>      if (maxlen < l)
>         maxlen = l
>  }
>
>

--
Link King
king@kinger.net


Report this thread to moderator Post Follow-up to this message
Old Post
Link King
03-20-04 01:23 AM


Re: Formatting
In article <Pine.LNX.4.44.0402111427350.31826-100000@mogul.kinger.net>,
Link King  <king@kinger.net> wrote:

% I'm close with the pointers you've given but not quite there.  Two things
% in particular.  One, the hosts/records are not printing out in the order

I should have mentioned that. It's a characteristic of

for (x in y)

processing that the data comes in an unpredictable order. What you need
to do if you want to preserve order is keep track of the hosts
in another array

h[NR] = $2 # at the same time as you load the other array


then loop through this array sequentially instead of using for (x in y)

for (i = 1; i <= NR; i++) {
name = h[i]

nf = split(info[name], f, /, */)

# etc

You don't have to assign h[i] to name, but it's probably a little faster
and easier to read if you do, and (the real reason) I don't have to
include a changed version of my previous posting with name changed
to h[i].


% 10.10.10.10 (xyz.abc.com)              53/open/tcp//domain

This looks like there are tabs after the colons in your input file.
You could try

BEGIN { FS = " *(INFO)?:[ \t]+" }

or use sub to remove leading whitespace before printing f[1].

--

Patrick TJ McPhee
East York  Canada
ptjm@interlog.com

Report this thread to moderator Post Follow-up to this message
Old Post
Patrick TJ McPhee
03-20-04 01:23 AM


Sponsored Links




Last Thread Next Thread Next
Search this forum -> 
Post New Thread

AWK archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 05:51 AM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.