You should use /dev/stderr
or /dev/fd/2
instead of /proc/self/fd/2
. gawk
handles /dev/fd/x
and /dev/stderr
by itself (regardless of whether the system has those files or not).
When you do a:
print "x" > "/dev/fd/2"
gawk
does a write(2, "x\n")
, while when you do:
print "x" > "/proc/self/fd/2"
since it doesn't treat /proc/self/fd/x
specially, it does a:
fd = open("/proc/self/fd/2", O_WRONLY|O_CREAT|O_TRUNC);
write(fd, "x\n");
First /proc/self/fd
is Linux specific and on Linux they are problematic. The two versions above are not equivalent when stderr is to a regular or other seekable file or to a socket (for which the latter would fail) (not to mention that it wastes a file descriptor).
That being said, if you need to write to the original stdout, you need to save it away in another fd like:
gawk -i /usr/share/awk/inplace.awk '{
print "goes into the-file"
print "to stdout" > "/dev/fd/3"}' the-file 3>&1
gawk
does redirect stdout with in-place to the file. It's needed because for instance, you'd want:
awk -i /usr/share/awk/inplace.awk '{system("uname")}' file
to store the uname
output into the file
.
In any case, do not use -i inplace
as gawk
tries to load the inplace
extension (as inplace
or inplace.awk
) from the current working directory first, where someone could have planted malware. The path of the inplace
extension supplied with gawk
may vary with the system, see the output of gawk 'BEGIN{print ENVIRON["AWKPATH"]}'
find -type f -name 'myfiles' -exec grep -q 'pattern' {} \; -print -exec gawk -i inplace '{do_your_sub_and_print_to_dev/stderr_too}' {} \;
that way you will only use awk to edit the files that actually contain lines matching that pattern. – don_crissti Nov 08 '16 at 01:14grep
can be. My first instinct is to avoid having to "process" the file twice, but I wouldn't be at all surprised if it is indeed faster nonetheless. It just goes to show why I can trust my gut on profiling tasks – Eric Renouf Nov 08 '16 at 01:19-print -exec gawk
is not executed anymore) and 2) it will stop at 1st match so unless the 1st match is on the last line you're still not processing the whole file twice (it's more like 1.X times) . Also, ifgawk -i inplace
works likesed -i
it will edit the file in-place anyway - i.e. updating timestamps, inode etc even if there was nothing to edit... – don_crissti Nov 08 '16 at 01:27$AWKPATH
not to include.
or make sure you run that command from within a working directory where nobody could create a file calledinplace
orinplace.awk
. – Stéphane Chazelas Jun 24 '23 at 21:14