Check if a file exists with wildcard in shell script [duplicate] Check if a file exists with wildcard in shell script [duplicate] shell shell

Check if a file exists with wildcard in shell script [duplicate]


Update: For bash scripts, the most direct and performant approach is:

if compgen -G "${PROJECT_DIR}/*.png" > /dev/null; then    echo "pattern exists!"fi

This will work very speedily even in directories with millions of files and does not involve a new subshell.

Source


The simplest should be to rely on ls return value (it returns non-zero when the files do not exist):

if ls /path/to/your/files* 1> /dev/null 2>&1; then    echo "files do exist"else    echo "files do not exist"fi

I redirected the ls output to make it completely silent.


EDIT: Since this answer has got a bit of attention (and very useful critic remarks as comments), here is an optimization that also relies on glob expansion, but avoids the use of ls:

for f in /path/to/your/files*; do    ## Check if the glob gets expanded to existing files.    ## If not, f here will be exactly the pattern above    ## and the exists test will evaluate to false.    [ -e "$f" ] && echo "files do exist" || echo "files do not exist"    ## This is all we needed to know, so we can break after the first iteration    breakdone

This is very similar to @grok12's answer, but it avoids the unnecessary iteration through the whole list.


If your shell has a nullglob option and it's turned on, a wildcard pattern that matches no files will be removed from the command line altogether. This will make ls see no pathname arguments, list the contents of the current directory and succeed, which is wrong. GNU stat, which always fails if given no arguments or an argument naming a nonexistent file, would be more robust. Also, the &> redirection operator is a bashism.

if stat --printf='' /path/to/your/files* 2>/dev/nullthen    echo foundelse    echo not foundfi

Better still is GNU find, which can handle a wildcard search internally and exit as soon as at it finds one matching file, rather than waste time processing a potentially huge list of them expanded by the shell; this also avoids the risk that the shell might overflow its command line buffer.

if test -n "$(find /dir/to/search -maxdepth 1 -name 'files*' -print -quit)"then    echo foundelse    echo not foundfi

Non-GNU versions of find might not have the -maxdepth option used here to make find search only the /dir/to/search instead of the entire directory tree rooted there.


Here is my answer -

files=(xorg-x11-fonts*)if [ -e "${files[0]}" ];then    printf "BLAH"fi