[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: How do I determine the existence (or non-existence) of a file from a
From: |
Alan Mackenzie |
Subject: |
Re: How do I determine the existence (or non-existence) of a file from an AWK script? |
Date: |
Tue, 11 Apr 2023 14:07:23 +0000 |
Hello, Andy.
On Mon, Apr 10, 2023 at 16:55:27 -0400, Andrew J. Schorr wrote:
> Hi,
> On Mon, Apr 10, 2023 at 05:41:22PM +0000, Alan Mackenzie wrote:
> > This should be something quite simple, but I can't work out how to do it.
> > Given a file name in an AWK script, does a file with that name actually
> > exist? In a shell script, I'd simply do [ -f "$FOO" ]. What do I have
> > to do in AWK?
> > The context is a script which checks certain syntactic things in a git
> > commit message. I want to extend it to check that the noted file names
> > in the commit message don't have typos, or missing directory parts, that
> > kind of thing.
> Here are a couple of efficient solutions that don't involve running a child
> process.
> 1. Use getline to try to read from the file. Some examples:
> bash-5.1$ gawk -v fn=/tmp/bogus 'BEGIN {if ((rc = (getline x < fn)) >= 0)
> {printf "%s exists and I can read it\n", fn; close(fn)} else printf "I cannot
> read %s; ERRNO is [%s]\n", fn, ERRNO}'
> I cannot read /tmp/bogus; ERRNO is [No such file or directory]
> bash-5.1$ gawk -v fn=/etc/passwd 'BEGIN {if ((rc = (getline x < fn)) >= 0)
> {printf "%s exists and I can read it\n", fn; close(fn)} else printf "I cannot
> read %s; ERRNO is [%s]\n", fn, ERRNO}'
> /etc/passwd exists and I can read it
> bash-5.1$ gawk -v fn=/etc/shadow 'BEGIN {if ((rc = (getline x < fn)) >= 0)
> {printf "%s exists and I can read it\n", fn; close(fn)} else printf "I cannot
> read %s; ERRNO is [%s]\n", fn, ERRNO}'
> I cannot read /etc/shadow; ERRNO is [Permission denied]
> 2. Use the filefuncs stat extension. It is documented here:
> https://www.gnu.org/software/gawk/manual/html_node/Extension-Sample-File-Functions.html
> Some examples:
> sh-5.1$ gawk -lfilefuncs -v fn=/tmp/fubar 'BEGIN {print stat(fn, st), ERRNO;
> printf "%o\n", st["mode"]}'
> -1 No such file or directory
> 0
> bash-5.1$ gawk -lfilefuncs -v fn=/etc/passwd 'BEGIN {print stat(fn, st),
> ERRNO; printf "%o\n", st["mode"]}'
> 0
> 100444
> bash-5.1$ gawk -lfilefuncs -v fn=/etc/shadow 'BEGIN {print stat(fn, st),
> ERRNO; printf "%o\n", st["mode"]}'
> 0
> 100000
Many thanks. I've gone for your first solution, which should hopefully
work in any POSIX conformant AWK, not just gawk. It has the slight
disadvantage of giving an error for a read only file, but I think it will
be very rare for anybody to want to commit such a file with git.
> Regards,
> Andy
--
Alan Mackenzie (Nuremberg, Germany).