views:

165

answers:

3

Hi there!

I want to embed an awk script inside a shell script but I have trouble to do so as I don't know where to end a statement with a ; and where not.

Here's my script

#!/bin/sh

awk='

BEGIN {FS = ",?+" }

# removes all backspaces preceded by any char except _
function format() {
    gsub("[^_]\b", "")
}

function getOptions() {
    getline
    format() 

    print
}

{
    format()

    if ($0 ~ /^SYNOPSIS$/ {
        getOptions()
        next            
    }

    if ($0  /^[ \t]+--?[A-Za-z0-9]+/) {
        print $0
    }
}

END { print "\n" }'

path='/usr/share/man/man1'
list=$(ls $path)

for item in $list
do
    echo "Command: $item"
    zcat $path$item | nroff -man | awk "$awk"
done > opts

I'm using nawk by the way.

Thanks in advance

A: 

i am not really sure what you meant, but if i understand you correctly, your showOpts.awk is that awk code at the beginning of your script, so you could do this

path='/usr/share/man/man1'
list=$(ls $path)

for item in $list
do
    echo "Command: $item"
    zcat $path$item | nroff -man | nawk ' BEGIN {FS = ",?+" }
# removes all backspaces preceded by any char except _
function format() {
    gsub("[^_]\b", "")
}

function getOptions() {
    getline
    format()

    print
}

{
    format()

    if ($0 ~ /^SYNOPSIS$/ {
        getOptions()
        next
    }

    if ($0  /^[ \t]+--?[A-Za-z0-9]+/) {
        print $0
    }
}

END { print "\n" } '
done >> opts

and you should probably use >> instead of > .

ghostdog74
I'd suggest that embedding the literal awk program into the loop like that makes the entire shell script very hard to read. Assigning it to a variable first (like the OP was trying to do) and then invoking `awk "$awk"` is much more readable.
Dale Hagglund
Since the redirect is outside the loop, there's no reason that it has to be an append.
Dennis Williamson
+3  A: 

There are several things wrong, as far as I can see:

  1. You don't close the multi-line string being assigned to $awk. You need a single quote on the line after END { ... }
  2. You don't seem to actually use $awk anywhere. Perhaps you meant on the invocation of awk inside the do loop.
  3. Once you fix those issues, awk is usually fairly forgiving about semicolons, but any problems in that regard don't have anything to do with using it inside a shell script.
Dale Hagglund
+2  A: 

These three lines:

path='/usr/share/man/man1'

list=$(ls $path)

for item in $list

Need to be changed into:

path='/usr/share/man/man1'

for item in $path/*

in case there are spaces in filenames and since ls is not intended to be used in this way.

Dennis Williamson
After this good change, `$path$item` should be just `$item`. And also, the variable expansions should be quoted. So, `zcat "$item" | nroff -man | awk "$awk"`
Chris Johnsen
You're right, thanks.
Dennis Williamson