Question

The code

 #!/usr/bin/awk            

 # Sed and AWK by O'Reilly (p.179)

 # Example of what should happen: factorial 5 gives
 #   factorial
 #   Enter number: 3
 #   The factorial of 3 is 6


 BEGIN {
     printf("Enter number: ")
 }

 $1 ~ /^[0-9]+$/ {
     # assign value of $1 to number & fact
     number = $1 
     if (number == 0) 
         fact = 1
     else
         fact = number

     for (x = 1; x < number; x++)
         fact *=x
     printf("The factorial of %d is %g\n", number, fact)

     exit
 }

 # if not a number, prompt again.
 { printf("\nInvalid entry. Enter a number: ")
 }

I run the command unsuccessfully by

./factorial.awk

I get

/usr/bin/awk: syntax error at source line 1
 context is
         >>>  <<< ./factorial.awk
/usr/bin/awk: bailing out at source line 1

What does the error message mean?

Was it helpful?

Solution

I think that the problem is that you are writing a shell script and passing it to awk for execution. The following is a shell script, hence the #! /bin/sh, so it will be passed to the shell (Bourne-compatible in this case).

#! /bin/sh
awk 'BEGIN { printf("Hello world!\n"); exit }'

The she-bang (#!) line tells the current interpreter which interpreter to pass the script to for execution. You have to pass the script to the awk interpreter so you need to call awk explicitly. This assumes that awk is in your path somewhere.

The following, however, is an awk script.

#! /usr/bin/awk -f
BEGIN {
    printf("Hello world!\n");
    exit
}

The she-bang invokes awk and passes the script as input. You don't need to explicitly invoke awk in this case and you don't have to quote the entire script since it is passed directly to awk.

Think of the she-bang as saying take what follows the she-bang, append the name of the file, and execute it. Wikipedia describes the usage pretty well including some common ways to solve the path to the interpreter problem.

OTHER TIPS

Possibly a dumb answer but in my terminal I would have to type in:

./factorial.awk

where the file is factorial.awk.

You could edit your path environment variable to include . but ./ should work just fine I think. And adding . to $PATH could prove to be very dangerous in some situations where you would run code that you did not expect to.

Does that work??

EDIT:

./factorial.awk -bash: ./factorial.awk: /usr/bin/gawk: bad interpreter: No such file or directory

That says that it ran the file but could not find the program gawk. Please type in 'which gawk' and then 'which awk'.

Is your first line supposed to be:

#!/usr/bin/awk

Also, just to amuse me, type in:

sudo apt-get install gawk

That will make sure you actually have gawk on your system.

EDIT2: I took a look at your code and this is what I have now. I removed two quotes and a dash.

#!/usr/bin/gawk                                                                                                                                        

# I think we do not need these (p.179) so I comment them out, since I do not know where else to put them.
# The same bug occurs also with them.
#fact = number
#for (x = number -1 ; x > 1; x--)
#    fact *= x

awk # factorial: returns factorial of user-supplied number
    BEGIN {
    printf("Enter number: ")
    }

   $1 ~ /^[0-9]+$/ {
   # assign value of $1 to number & fact
   number = $1 
   if (number == 0) 
       fact = 1
   else
       fact = number
   #loop to multiply fact*x until x = 1
   for (x = number - 1; x > 1; x--)
       fact *= x
   printf("The factorial of %d is %g\n", number, fact)
   #exit -- saves user from typing ^-d
   exit
}

# if not a number, prompt again.
{ printf("\nInvalid entry. Enter a number: ")
}

may be it wasn't that complicated.

#!/usr/bin/awk ---------> #!/usr/bin/awk -f

Check whether there is a file /usr/bin/gawk; if not, use either the path of awk or the correct location for gawk.

Also, did you make the script executable?

And also, do you have the current directory in your PATH?

I got the script to work in Ubuntu and OS X by running

awk -f factorial.awk

It seems that you cannot run the script as follows although the book says so

./factorial.awk 

Here's a recursive version:

#!/usr/bin/awk -f
function f(x) {
    if (x <= 1) return 1
    return (f(x-1) *x)} 

BEGIN {
    printf("Enter number: ")
}

$1 ~ /^[0-9]+$/ {
    printf("The factorial of %d is %d\n", $1, f($1))
    exit
}

{ printf("\nInvalid entry. Enter a number: ")
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top