Unable to make a factorial function in AWK

时光怂恿深爱的人放手 提交于 2019-12-13 10:28:33

问题


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?


回答1:


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.




回答2:


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: ")
}



回答3:


may be it wasn't that complicated.

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




回答4:


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?




回答5:


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 



回答6:


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: ")
}


来源:https://stackoverflow.com/questions/787858/unable-to-make-a-factorial-function-in-awk

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!