awk -f script.awk: run an awk program from a file
- tool
- awk
- command
- awk
- flag
- -f progfile
- default
- off (the first non-option argument is the program text)
awk -f report.awk data.txt reads the awk program from report.awk instead of from the command line. Use it when a program outgrows a one-liner: the file needs no shell quoting, can hold comments and functions, and can be reused. -f is POSIX and can be repeated; gawk's long form is --file=progfile.
One file, several files, mixed with -e
printf '{ print $1 }\n' > first.awk
echo 'hi there' | awk -f first.awk
printf 'function dbl(x) { return 2 * x }\n' > lib.awk
printf '{ print dbl($1) }\n' > main.awk
echo 21 | awk -f lib.awk -f main.awk
echo 3 | awk -f main.awk -e 'function dbl(x) { return x * 10 }'Output
hi 42 30
Several -f files are concatenated in the order given, so a library of functions can live in its own file. -e (--source) is a gawk extension that adds program text from the command line to the same program.
The program file changes how arguments are read
Without -f, the first non-option argument is the program. With -f, it is an input file. Adding a quoted program after -f is a common mistake:
printf '{ print $1 }\n' > main.awk
echo 5 | awk -f main.awk '{ print "x" }'Output · exit 2
awk: fatal: cannot open file `{ print "x" }' for reading: No such file or directoryawk takes { print "x" } as a file name and fails to open it.
Executable awk scripts
A #! line turns the file into a command. Arguments after the script name reach awk as usual and appear in ARGV:
printf '#!/usr/bin/awk -f\nBEGIN { print "args:", ARGV[1] }\n' > hello.awk
awk -f hello.awk worldOutput
args: world
On a system where awk lives elsewhere, use the real path in the #! line; #!/usr/bin/env awk -f does not work everywhere, because many kernels pass awk -f to env as a single argument.
Related options
| Option | What it does | Standard |
|---|---|---|
| -f progfile | Read program text from a file; repeatable | POSIX |
| -e 'text', --source | Add program text from the command line; mixes with -f | gawk |
| -i file, --include | Load a library once, even if included twice | gawk |
| -E file, --exec | Like -f but ends option parsing; for #! scripts that must not accept awk options | gawk |
| -v var=value | Assign a variable before BEGIN | POSIX |
Errors
awk -f missing.awkOutput · exit 2
awk: fatal: cannot open source file `missing.awk' for reading: No such file or directory
gawk stops with exit 2 when it cannot open a program file. A syntax error inside the file reports the file name and line number instead of cmd. line:, which makes it easier to find than the command-line syntax error:
printf 'BEGIN {\n x = 1\n print (\n}\n' > bad.awk
awk -f bad.awkOutput · exit 1
awk: bad.awk:4: print ( awk: bad.awk:4: ^ unexpected newline or end of string
The same file cannot be loaded both with -f and with gawk's -i: gawk refuses to include a file and also use it as a program file. Variables are passed into a file program the same way as into a one-liner, with awk -v.
FAQ
Can I use -f together with a program on the command line?
Not in POSIX awk: once -f is given, every non-option argument is an input file. gawk adds -e 'program text', which can be mixed with -f; all pieces are joined in order.
How do I make an awk script executable?
Start it with #!/usr/bin/awk -f (or the path of gawk), chmod +x it and run ./script.awk file. The kernel appends the script path after -f, so awk reads the program from it.
Does the script file need the .awk extension?
No. Any file name works. gawk also searches AWKPATH for -f files that are not found by their path and tries the name with .awk added.