/errors/awk/fatal-cannot-open-file-for-reading
awk: fatal: cannot open file `file' for reading: No such file or directory
- tool
- awk
- exit code
- 2
- versions
- GNU Awk 4.x – 5.x
- os
- linux, macos, windows
awk: fatal: cannot open file `data.txt' for reading: No such file or directory means gawk treated an argument as an input file and could not open it. Either the file really is missing (check the path and the current directory), or an argument was split or misread, usually because of shell quoting or an assignment written with spaces. gawk exits with status 2 at the first file it cannot open.
Reproduce the error
awk '{ print $1 }' data.txtOutput · exit 2
awk: fatal: cannot open file `data.txt' for reading: No such file or directory
An unquoted variable that holds a file name with a space is split by the shell into two names:
printf 'a 1\nb 2\n' > "my data.txt"
f="my data.txt"
awk '{ print $1 }' $fOutput · exit 2
awk: fatal: cannot open file `my' for reading: No such file or directory
Fix: check the file and the quoting
printf 'a 1\nb 2\n' > data.txt
ls -l data.txt | cut -c1
awk '{ print $1 }' data.txtOutput
- a b
Assignments that look like files
After the program, an argument of the form name=value is a variable assignment, not a file. Spaces around = break it into three arguments, and awk tries to open a file named n:
printf 'a 1\nb 2\n' > data.txt
awk '{ print $1 * n }' n = 10 data.txtOutput · exit 2
awk: fatal: cannot open file `n' for reading: No such file or directory
Write it without spaces, or with -v so the value is set before BEGIN runs:
printf 'a 1\nb 2\n' > data.txt
awk -v n=10 '{ print $1, $2 * n }' data.txt
awk '{ print $1, $2 * n }' n=10 data.txtOutput
a 10 b 20 a 10 b 20
A real file whose name contains = must be written as ./name=x.txt, otherwise awk assigns a variable instead of reading the file.
How to recognise each cause
The name between the quotes tells you which cause you have. If it is the file you meant, the path is wrong: compare it with pwd and ls. If it is a fragment of a name (my, data.txt without the directory), the shell split an unquoted variable. If it is a variable name or =, an assignment was written with spaces. If the message says cannot open source file, the -f program file is missing rather than the data file.
Earlier files are processed first
awk opens its input files one at a time, so output from the files before the missing one is printed before the error, and the files after it are never read. The message then carries the program location prefix:
echo 'a 1' > one.txt
awk '{ print FILENAME, $1 }' one.txt missing.txt one.txtOutput · exit 2
one.txt a awk: cmd. line:1: fatal: cannot open file `missing.txt' for reading: No such file or directory
In a pipeline, that partial output can look like a successful run. Check awk's exit status, or use set -o pipefail so the pipeline reports the failure.
Prevent it in scripts
- Quote every expansion that holds a path:
awk '...' "$file"and"${files[@]}"for arrays. - Test the file before calling awk when a missing file is expected, for example
[ -r "$file" ] || { echo "missing: $file" >&2; exit 1; }. - Pass values with
-v name=valuerather than trailingname=valuearguments, so there is never an argument awk could mistake for a file. - A directory argument is not fatal: gawk prints
warning: command line argument ... is a directory: skippedand continues.
FAQ
Does awk stop at the first missing file or skip it?
gawk stops: it processes the files before the missing one, prints the fatal message and exits with status 2 without reading the files after it. To skip unreadable files instead, test them in the shell first or use the BEGINFILE and ERRNO features of gawk.
Why is the message sometimes prefixed with cmd. line:1:?
When the failure happens after awk has started running the program, for example on the second file, gawk adds the source location of the program to the message. The cause and the fix are the same.
What does cannot open source file mean?
That variant refers to a program file given with -f prog.awk, not to an input file. Check the path to the .awk script, which is resolved relative to the current directory or the AWKPATH directories.