My shell script is something like this:
#!/bin/bash
global_var=0
func() {
awk '$1 ~/^pattern/ {global_var=$((global_var+1))}' $1
}
func input_file_name
I want to increment the global (shell) variable global_var
inside the awk
action. How to do so? Normal shell style incrementing does not seem to be working.
Try this:
func() {
awk '$1~/^pattern/ {++awk_var} END {print awk_var+0}' "$1"
}
shell_var=$(func input_file_name)
The shell and awk
are separate worlds, and you should treat them as such(*) (which, in effect, you're already doing, by enclosing your awk
program in single quotes, which prevents the shell from expanding any shell variable references in your akw
program string).
Thus, use an awk
[-internal] variable to perform your counting (awk_var
) and output it after having finished processing the input file (in the END
block, using print
to output the awk
variable to stdout
- the +0
part is to ensure that the output defaults to 0
in case NO match was found.)
Note that, generally, awk
variables need no explicit initialization, because they default to 0
in numerical and Boolean contexts, and to ""
(empty string) in string contexts).
Also note that awk
has its own syntax, and shell constructs such as $((...))
for arithmetic expansion do not apply. Generally, awk
variables are referred to just by name (no $
prefix), and arithmetic operations such as ++
can be applied directly.
Using command substitution - $(...)
- in the shell then allows you to capture output from the awk
command.
In your specific case you have no need to pass variable values into the awk
program, but if you needed to do that, you'd use one or more instances of awk
's -v
option; e.g.: awk -v awk_var="$shell_var" ...
On the shell (bash
) side, if you wanted to add awk
's output to the shell variable instead of just assigning it:
declare -i shell_var # make sure variable is an integer
shell_var+=$(func input_file_name) # add function's output to existing value
(*) The shell and awk
have completely separate namespaces that have no direct way of interacting with one another: awk
has no concept of shell variables, and the shell has no concept of awk
variables.
It is technically feasible, but ill-advised to integrate shell variable VALUES into an awk
program - by using a double-quoted string to represent the awk
program in which you reference shell variable VALUES, which are then expanded by the shell ONCE, BEFORE the string gets passed as a program to awk
.
What you CANNOT do is to modify a shell variable from inside an awk
program.
Since it gets complicated quickly as to which parts of the awk
program are interpreted by the shell up front vs. which parts are interpreted by awk
later (where '$
has special meaning too, for instance), the best approach is to:
awk
program, so as to protect it from interpretation by the shell-v
optionstdout
from awk
and use command substitution or redirection to capture it via the shell.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With