UNIX Programming, Certification, System Administration, Performance Tuning Reference Books
Help with getline using nawk

I am having problems with getline, or maybe I don't understand how to use it correctly.

KSH SCRIPT:
print "starting script ....."
while read LINE; do
print "Reading line $LINE"
CHOICES=$(echo "$LINE" | nawk -F "[()]" '$0 ~ ".*(.+[/].+)[:space:]*.*|.*(.+[-].+)[:space:]*.*" {print $2}')
if [[ -n $CHOICES ]]; then
print "I have choices"
else
print "I am in the else"
CHOICES=$(nawk -F"[(]" '$0 ~ ".*[/]$"{
while(substr($0,length,1)=="/")
{rc=getline nextline
if (rc==0)
break
else
$0=$0 nextline}
print
exit
}'|sed -e 's/\! *//g' -e 's/)//g')
fi
print "My choices are: $CHOICES"
done < myjunk

INPUT:
! param1 (A/B/C)
! param2 (stop/
! go/
! refresh/
! delete)
! param3 (yes/no)

OUPUT:
starting script .....
Reading line ! param1 (A/B/C)
I have choices
My choices are: A/B/C
Reading line ! param2 (stop/
I am in the else
My choices are: go/refresh/delete
Reading line ! param3 (yes/no)
I have choices
My choices are: yes/no

How do I get the desired output for param2 to on one line like:
My choices are: stop/go/refresh/delete

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CHOICES=$(nawk -F"[(]" '$0 ~ ".*[/]$"{
while(substr($0,length,1)=="/")
{rc=getline nextline
if (rc==0)
break
else
$0=$0 nextline}
print
exit
}'|sed -e 's/\! *//g' -e 's/)//g')

Your nawk script doesn't have input file specified, so it reads records from stdin.

The nawk command is in a loop which reads your input file, but nawk doesn't share it with the shell.

Format the input file whit nawk and read the result in a loop (see the example in your previous thread).

nawk ' . . . . ' myjunk | \
while read LINE
do
???. . . .
done

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Parsing Patterns

I am trying to parse a pattern that could or could not span mulitple lines. Right now, my script only catches the pattern if it is contained in one line.

For example:
(A/B/BOTH) --- parses fine

BUT this doesn't
(A/
B/
Both)

How can I change this line to parse both instances?

CHOICES=$(echo "$LINE" | nawk -F "[()]" '$0 ~ ".*(.+[/].+)[:space:]*.*" {print $2}')

I am reading the file line by line and the code above is within a while read $LINE , loop

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Since you read your file line by and treat each line separately, your line will never match a pattern which can contains a new line.  You must change the logic of your script. Do you really need to read your file line by by line ?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
What other options are there?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
That depends on the contents of the file and what you want to make with it.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here is what the file looks like
param1 (A/B/C)
param2 (stop/
go/
refresh/
delete)

The param1 and param2 are labels on a dialog box and the options within parens are the values being populated in a dropdown list. I am trying to figure out a way to parse out the options that span multiple lines. I have 300+ of these header files that I am using this parsing tool on.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Since you are already using nawk, one approach would be to have nawk append any number of following lines as long as the current line ends with a slash.

Following code does that. If I do not check the getline return code (rc), if the very last line ends with a slash I would loop forever.

You would replace the unconditional print statement with an if match statement.

nawk '{
while (substr($0,length,1) == "/")
??{rc=getline nextline
???if (rc==0)
??????break
???else
??????$0=$0 nextline}
print
}' kromo.txt

Input file:
param1 (A/B/C)
param2 (stop/
go/
refresh/
delete)

Output file:
param1 (A/B/C)
param2 (stop/go/refresh/delete)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I can't get this example to work, can someone show me how?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The script works fine for me.
Have you error messages ? What output did you get ?

I have modified the awk script a little bit.
For lines matching the format 'label (list) ', it print 'label list'

awk ?'
BEGIN ?{
??FS="[()]" ?; ?OFS=" ?";
}
{
??while ?(substr($0,length,1) ?== ?"/") ?{
????rc=getline ?nextline;
????if ?(rc==0)
???????break;
????else
???????$0=$0 ?nextline
??}
??if ?($0 ?~ ?/.*\(.+(\/.+)*\)[:space:]*.*/)
?????print ?$1 ?$2;
}
' ?kromo.txt ?|?\
while ?read ??Label ?List
do
???echo ?"Label ?Box: ?$Label, ?Dropdown ?List ?: ?$List"
done

The result is :

Label Box: param1, Dropdown List : A/B/C
Label Box: param2, Dropdown List : stop/go/refresh/delete

Just for the fun, the 'awk' script can be replaced by a 'sed' script (not recommended, the 'sed' script is unreadable).

sed -n '
:loop
/\/$/N
s/\n//
t loop
\!.*(.\+\(/.\+\)[:space:]*.*! {
s/[()]/ /g
p
} ' kromo.txt

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In regards to the Jim script, for some reason the return code comes back as 0 after every two lines. So out put looks like this:
param2 (stop/
param2 (stop/
go/

go/
refresh/

refresh/
delete)
 

What could be causing the rc to be 0 when the end of file has not been reached??? And why isn't my output being concatenated on one line as the example above?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I?can't?reproduce?your?problem.
Verify?your?script.
If?you?don't?found?error,?add?debugging?print?statements?and?post?us?the?result?:

awk?'{
print?"\ndbg?-?Initial?line?$0:"?$0;
while?(substr($0,length,1)?==?"/")
???{rc=getline?nextline
print?"dbg?-?current?record?$0:"?$0;
print?"dbg?-?end?with?/,?rc:"?rc?",?nextline:"?nextline;
???if?(rc==0)
??????break
???else
??????$0=$0?nextline}
print
}'?kromo.txt

The result I got :

dbg?-?Initial?line?$0:param1?(A/B/C)
param1?(A/B/C)

dbg?-?Initial?line?$0:param2?(stop/
dbg?-?current?record?$0:param2?(stop/
dbg?-?end?with?/,?rc:1,?nextline:go/
dbg?-?current?record?$0:param2?(stop/go/
dbg?-?end?with?/,?rc:1,?nextline:refresh/
dbg?-?current?record?$0:param2?(stop/go/refresh/
dbg?-?end?with?/,?rc:1,?nextline:delete)
param2?(stop/go/refresh/delete)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SCRIPT:
print "starting script ....."
while read LINE; do
print "Reading line $LINE"
nawk '{
while(substr($0,length,1)=="/")
{rc=getline nextline
if (rc==0)
break
else
$0=$0 nextline
}
print
exit
}'|sed 's/\! *//g'
done < myjunk
INPUT:
! param1 (A/B/C)
! param2 (stop/
! go/
! refresh/
! delete)
! param3 (yes/no)

OUTPUT:
starting script .....
Reading line ! param1 (A/B/C)
param2 (stop/go/refresh/delete)
Reading line ! param3 (yes/no)

Notice the number of "Reading line " shouldn't it loop through at least 3 times???

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(more info from previous message)
REVISED SCRIPT:
print "starting script ....."
while read LINE; do
print "Reading line $LINE"
CHOICES=$(echo "$LINE" | nawk -F "[()]" '$0 ~ ".*(.+[/].+)[:space:]*.*" {print $2}')
if [[ -n $CHOICES ]]; then
print "I have choices"
else
print "I am in the else"
nawk '{
while(substr($0,length,1)=="/")
{rc=getline nextline
if (rc==0)
break
else
$0=$0 nextline
}
print
exit
}'|sed 's/\! *//g'
fi
print "My choices are: $CHOICES"
done < myjunk

OUTPUT:
starting script .....
Reading line ! param1 (A/B/C)
I have choices
My choices are: A/B/C
Reading line ! param2 (stop/
I am in the else
go/refresh/delete)
My choices are:
Reading line ! param3 (yes/no)
I have choices
My choices are: yes/no

** How do I change the script to put all of param2's options on the same line and strip out the param2
Desired output for param2 is:
stop/go/refresh/delete

What am i doing wrong???

Quick Links:
Do you have a UNIX Question?

Unix Home: Unix System Administration Hints and Tips