Because AWK is not shell, and it isn't Perl.
Firstly variables in AWK are referenced by name only, you do not apply $ in front of words to reference the words as a variable - if you want to access a variable called name, you refer to it as name (just like C).
Secondly, AWK is like C (not shell), it does not expand variables inside string constants. It couldn't if it wanted to, because there is no way to distinguish words in a string constant from variables. So "hello name" is a constant string, regardless of whether name is a variable in the AWK script. Instead you construct new strings from string constants and variables, using the string concatenation operator, which rather unfortunately happens to be any whitespace. E.g:
# print the concatenation of a string and a variable directly print "hello " name; # concatenate, assign to 'newstr' and print that newstr = "hello " name; print newstr; # the print statement also recognises ',' as a "concatenate with # seperator" operator, using the ORS variable. # So, presuming ORS is " ", the # following is the equivalent to the first example above: print "hello", name;
$ is the "field reference" operator in AWK. It references the field in the current input record given by the variable or constant. E.g. if you want to print the first field, the following are equivalent:
# print the first field using the '$' operator and a constant. print $1; # same but with a variable instead of a constant i = 1; print $i;
The power of awk is in learning to use field references, some further examples:
# print both the value of i, and the field at $i.. print i, $i; # print the field at $i, but only if it something other than the empty # string: if ($i) print $i;
AWK sets the built-in variable NF to the Number of Fields the current line was split into. So just apply the field reference operator, $, to it:
print $NF;
Just iterate from field 3 through to the last field ($NF):
for (i = 3; i <= NF; i++) print $i;
Use the -v argument to awk to assign values to AWK variables:
$ FOO=bar; awk -v myvar=$FOO 'BEGIN { print myvar }'
bar
Use the system() function, e.g.:
cmd = "/bin/echo hello"; system(cmd); close(cmd);
You can run anything you want with system(), not just shell scripts
Either set the ORS (Output Record Seperator) variable to " ", e.g.:
$ echo -e 'foo\nbar\nhar' | awk -v ORS=" " '{ print } END { printf "\n" }'
foo bar har
or print each using printf(), without printing a newline. Use NR and END to take care of the first line, and a terminating newline. E.g.:
$ echo -e 'foo\nbar\nhar' | awk '\
NR == 1 { printf("%s", $0); } \
NR != 1 { printf(" %s", $0); } \
END { printf("\n") }'
foo bar har
Short answer is that you can't, because the kernel won't parse a bang-path past the name of the script. The rest of the line is passed as a single string, in the second argument. I.e. this won't work:
#!/path/to/gawk --posix --re-interval -f ....awk script..
Instead, use a shell script, e.g.:
#!/bin/bash
gawk --posix --re-interval -v foo=$1 '
BEGIN {
print foo
}
'
Probably because you're forgetting to close a pipe. E.g:
for (cmd in commands) {
cmd | getline var;
close (cmd);
<do stuff with var>
}
You need to pass the "--re-interval" argument to GNU AWK to enable bounds/interval-expressions in regular expressions. E.g.:
echo 0x0000 | gawk --re-interval '{print substr($0, match($0, "[0-9]{2}"))}'
Probably because you didn't wait. There are a few people who try answer questions if they can, but they may be in a timezone 12 hours or more away from you and fast asleep (or they might be in same timezone but sleeping weird hours ;) ).
Asking a question and then leaving the channel within 5 or 10 minutes rarely will result in answer. While you're waiting, you can try reading some of the documentation mentioned above, you might figure out the answer for yourself ;)
Send additions to paul or registered user paul on Freenode (usually in the #awk channel).