Search code examples
awkfactorial

Unable to make a factorial function in AWK


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?


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.