gawk -i inplace: edit a file in place with awk
- tool
- awk
- command
- gawk
- flag
- -i inplace
- default
- off (awk writes to standard output and never changes its input files)
gawk -i inplace '{ print $2, $1 }' data.txt rewrites data.txt with the program's output instead of printing it. -i (long form --include) loads an awk source library, and inplace is a library shipped with GNU Awk that redirects standard output into a temporary file for each input file and renames it over the original when that file ends. It is gawk's equivalent of sed -i. On most Linux systems awk is gawk, so awk -i inplace works too; on macOS (BSD awk) and with mawk it does not.
Basic use and a backup
printf 'a 1\nb 2\n' > f.txt
awk -i inplace '{ print $2, $1 }' f.txt
cat f.txt
awk -i inplace -v inplace::suffix=.bak '{ print toupper($0) }' f.txt
cat f.txt
cat f.txt.bakOutput
1 a 2 b 1 A 2 B 1 a 2 b
inplace::suffix names a backup copy of each original. Without it the original is gone once the file is rewritten, so test the program without -i inplace first.
Several files
Each file operand is edited separately; FILENAME and FNR refer to the file being rewritten:
printf 'a\n' > one.txt; printf 'b\n' > two.txt
awk -i inplace '{ print FILENAME ": " $0 }' one.txt two.txt
cat one.txt two.txtOutput
one.txt: a two.txt: b
Where output goes
| Output from | Destination with -i inplace |
|---|---|
| print / printf in main rules | the file being edited |
| BEGIN block | standard output (no file is open yet) |
| END block | standard output (the last file is already replaced) |
| print > "/dev/stderr" | the terminal; not written to the file |
| standard input (no file operand) | standard output, with a warning |
Pitfalls
printf 'keep\n' > two.txt
awk -i inplace 'END { print "done" }' two.txt
wc -c < two.txt
echo x | awk -i inplace '{ print }'Output
done 0 awk: inplace:62: warning: inplace::begin: disabling in-place editing for invalid FILENAME `-' x
- Lines the program does not print are deleted. The program above prints only in
END, sotwo.txtends up with 0 bytes. To change some lines and keep the rest, end the program with a bare1or{ print }:awk -i inplace '/^#/ { next } 1' fileremoves comment lines and keeps everything else. - Standard input cannot be edited. gawk warns that it is disabling in-place editing for the invalid FILENAME
-and prints to standard output. - A missing file is fatal. The extension warns it cannot stat the file and gawk stops with exit 2, as in cannot open file for reading.
-iis not-v.-itakes a library name or path (-i inplace,-i ./lib.awk); gawk searchesAWKPATHfor it and adds.awkif needed. Do not confuse it withsed -i, which is a plain option.
Alternatives
| Approach | Portable | Notes |
|---|---|---|
| gawk -i inplace | gawk only | Handles several files in one run |
| awk '...' f > f.tmp && mv f.tmp f | any awk | Never redirect to the input file itself: the shell truncates it first |
| sed -i | GNU and BSD sed (different syntax) | Better for simple substitutions |
FAQ
Does awk -i inplace work on macOS or with mawk?
No. -i inplace loads a gawk extension; the BSD awk on macOS and mawk do not have it. Install gawk, or write to a temporary file and move it over the original.
How do I keep a backup of the original file?
Set the suffix variable, gawk -i inplace -v inplace::suffix=.bak '...' file. gawk writes the original to file.bak before replacing file.
Why did my file become empty?
With -i inplace, whatever the main rules print becomes the new file. A program that prints nothing, or only to /dev/stderr, leaves an empty file. Add a final print for lines you want to keep.