0
#!/usr/bin/awk

userinput='Hello World!'
userinput=$userinput awk '
    BEGIN {
        s = ENVIRON["userinput"] "\n"
        n = length(s)
        while (1)
            printf "%s", substr(s,int(1+rand()*n),1)
    }'

Whenever I run above code I get following error.

awk: cmd. line:1: pass.awk
awk: cmd. line:1: ^ syntax error

#!/usr/bin/awk

awk '{
        s = $0 "\n"
        n = length(s)
        while (1)
            printf "%s", substr(s,int(1+rand()*n),1)
    }'

awk: cmd. line:1: pass.awk
awk: cmd. line:1: ^ syntax error

I am getting same error both time. But, I am not getting any error when I write those code and run in terminal. It was little bit weird for me. Cause, I am new to awk. That may be a typo error I am not sure. I had saved the file name as pass.awk. Running this way awk pass.awk or, awk pass.awk hello

1
  • 4
    What you have there is a shell script that uses awk, not an awk script - the #!/usr/bin/awk shebang is not appropriate May 6 at 16:13
3

There are two problems here. First, if you want to write an awk script, you need to use -f in the shebang since awk requires a file, and using this is a workaround to let you use awk on the contents of the script. See man awk:

   -f progfile
             Specify  the pathname of the file progfile containing an awk
             program. A pathname of '-' shall denote the standard  input.
             If multiple instances of this option are specified, the con‐
             catenation of the files specified as progfile in  the  order
             specified  shall be the awk program. The awk program can al‐
             ternatively be specified in the command line as a single ar‐
             gument.

So, to use awk as your interpreter in the shebang, you need this:

#!/bin/awk -f

BEGIN{print "hello world!"}

What you have is a shell script that is calling awk, so you need a shell shebang:

#!/bin/sh

awk 'BEGIN{ print "Hello world!"}'

The next issue is that you have a space in your variable but are using the variable unquoted. Always quote variables in shell scripts! What you wanted was this:

userinput='Hello World!'
userinput="$userinput" awk '...

Now, here's a working version of your first (shell) script:

#!/bin/sh

userinput='Hello World!'
userinput="$userinput" awk '
    BEGIN {
        s = ENVIRON["userinput"] "\n"
        n = length(s)
        while (1)
            printf "%s", substr(s,int(1+rand()*n),1)
    }'

Note that your while (1) means the script will never exit, that is an infinite loop.

And here's your second script as an actual awk script:

#!/usr/bin/awk -f

{
  s = $0 "\n"
  n = length(s)
  while (1)
    printf "%s", substr(s,int(1+rand()*n),1)
}
14
  • Why I have to use -f with shebang? What does that mean(What does it represent)?
    – user467213
    May 6 at 16:29
  • 1
    @Softunes see updated answer. -f is how you tell awk to read commands from a file and in this case, the file is the script you write. But if you use awk in the shebang, then you must have only awk code in the script.
    – terdon
    May 6 at 16:32
  • 1
    @ilkkachu given what the awk program does, that wouldn't make sense here. In other cases, yes of course.
    – terdon
    May 6 at 16:44
  • 1
    Don't call awk with a shebang? "Never" seems a bit strong, just for a use-case that's highly situational/rarely useful - especially when it's only to make use of what is arguably a bug (unfixable for legacy reasons) in awk's design (to use args with = in them for variable assignment, making it a) impossible to pass filenames with = to awk, and b) causing any such filenames to make variable assignments if used. It's awk's equivalent of the "filename called -rf" problem, but without -- to ameliorate it).
    – cas
    May 7 at 4:14
  • 1
    FWIW I just checked the hundred+ script files I have lying around on my laptop that contain an awk script and there are only 2 of them that don't contain something that's best done outside of that awk script. It's not that I couldn't do some of it in awk (e.g. validating arguments with awk instead of using getopts, or sorting the output, or checking the input file is non-empty or getting the size of the file up front, etc) but almost every script I have is best written as a shell script, not just an awk script, so in my experience it's rare for a stand-alone awk script to be the best solution.
    – Ed Morton
    May 7 at 14:40
2

Make that first line call the shell interpreter and not awk, as in

#!/usr/bin/env bash
0

By default, awk expects a string containing the program code as the first argument on the command line. E.g.

awk 'BEGIN{ print "hello" }'

would just print hello. So if you run

awk pass.awk

it tries to interpret pass.awk as awk code. The dot isn't valid awk syntax, so an error you get.

To have awk read the code from a file, use awk -f foo.awk, as @terdon's answer shows. (You'll want to fix the hashbang line and remove the shell stub as shown there.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy