bug-gawk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Native file exist check


From: Andrew J. Schorr
Subject: Re: Native file exist check
Date: Fri, 5 Jun 2020 11:14:16 -0400
User-agent: Mutt/1.5.21 (2010-09-15)

On Fri, Jun 05, 2020 at 09:38:07AM -0500, Peng Yu wrote:
> https://stackoverflow.com/questions/29284472/awk-check-file-exists
> 
> The following solution is shown above. But getline could potentially
> read too much (for example processing a binary file in which a line
> can be very long). Is there a more efficient awk native solution for
> checking whether a file exist?
> 
> function file_exists(file) {
>   n=(getline _ < file);
>   if (n > 0) {
>     print "Found: " file;
>     return 1;
>   } else if (n == 0) {
>     print "Empty: " file;
>     return 1;
>   } else {
>     print "Error: " file;
>     return 0;
>   }
> }

As discussed in the stack overflow question, the getline approach
doesn't really address how permissioning problems should be handled.
Nor does it clearly define what "exists" means. The bash test command
gives a more fine-grained approach. But if by "exists" you mean is this
a regular file that this process has permission to read, then getline
should be a workable solution.

However, this function above has lots of problems. It should be using local
variables to avoid polluting the global namespace, and it doesn't close the 
file.
A better solution would be:

function file_exists(file,   x) { 
        switch (getline x < file) {
        case 1:
                close(file)
        case 0:
                return 1
        default:
                # you could possibly inspect ERRNO and/or PROCINFO["errno"]
                # to decide how to handle various error conditions
                return 0
        }
}

If you're worried about long lines, you can change RS to protect against that.
I think something like this (untested) should work:

function file_exists(file,   save_RS, x, rc) {
        save_RS = RS
        RS = "[^0]"     # match almost anything. Not sure how to match any char
        switch (getline x < file) {
        case 1:
                close(file)
        case 0:
                rc = 1
                break
        default:
                # you could possibly inspect ERRNO and/or PROCINFO["errno"]
                # to decide how to handle various error conditions
                rc = 0
        }
        RS = save_RS
        return rc
}

My brain must be malfunctioning, because I can't find an RS value that
would match any possible character. But this should be good enough unless
the file is filled with "0" characters. Somebody who's more awake can
probably figure out a better RS value.

Regards,
Andy



reply via email to

[Prev in Thread] Current Thread [Next in Thread]