Take the 2-minute tour ×

I'm trying to check if a file exists, but with a wildcard. Here is my example:

if [ -f "xorg-x11-fonts*" ]; then
    printf "BLAH"

I have also tried it without the double quotes.

share|improve this question
Two bugs with your code: (1) The asterisk has to be outside the double quotes (a quoted asterisk loses it special wildcard meaning), and (2) if multiple files match the pattern, multiple arguments will be passed to the [ command, most likely causing [ to exit with an error and therefore be interpreted as no files matching. –  Richard Hansen Jun 17 '11 at 6:31

9 Answers 9

up vote 92 down vote accepted

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"
    echo "files do not exist"

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

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

share|improve this answer
A word of warning: In the Debian Almquist Shell (dash) — installed at /bin/sh in Debian and Ubuntu — &> seems to discard the exit code and that breaks this solution. A workaround is to redirect with > /dev/null 2>&1 instead. –  qerub Nov 20 '11 at 18:42
@Qerub: Thanks for the input. –  Costi Ciudatu Nov 21 '11 at 3:58
ls can be quite slow on a directory with many files (probably due to sorting). You may want to turn off sorting with -U, at least. –  musiphil Jun 21 '12 at 21:01
Would it be better to list the files into text file and look at that if you were dealing with a lot of searches? –  Mike Q Jun 13 at 16:35
@musiphil Thanks for the input. I edited the answer to add an optimized alternative which eliminates the use of ls. –  Costi Ciudatu Sep 27 at 14:57

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/null
    echo found
    echo not found

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)"
    echo found
    echo not found

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.

share|improve this answer
Letting find handle the wildcard is best because bash, as it expands the pattern, tries to sort the list of the matching file names, which is wasteful and can be expensive. –  musiphil Jun 21 '12 at 21:10

Here is my answer -


if [ -e "${files[0]}" ];
    printf "BLAH"
share|improve this answer
This is what worked for me, using zsh. –  duma Apr 22 at 14:37


Okay, now I definitely have the solution:

files=$(ls xorg-x11-fonts* 2> /dev/null | wc -l)
if [ "$files" != "0" ]
   echo "Exists"
    echo "None found."

> Exists
share|improve this answer
In my shell (zsh) it works if there is only one match to the glob, otherwise it expands all the files and the test fails (too many arguments.) –  Edward Thomson Jun 15 '11 at 20:02
Update my code. I'm sure this works, I just installed zsh and tested. –  Swift Jun 15 '11 at 20:20
Reupdated. My bad. –  Swift Jun 15 '11 at 20:33
for i in xorg-x11-fonts*; do
if [ -f "$i" ]; then printf "BLAH" fi

This will work with multiple files and with white space in file names.

share|improve this answer

Maybe this will help someone:

if [ "`echo xorg-x11-fonts*`" != "xorg-x11-fonts*" ]; then
    printf "BLAH"
share|improve this answer
Cute. I like it. –  MykennaC Sep 11 at 17:34

Try this


filesFound=$(ls $fileTarget)  # 2014-04-03 edit 2: removed dbl-qts around $(...)

edit 2014-04-03 (removed dbl-quotes and added test file 'Charlie 22.html' (2 spaces)

case ${filesFound} in
  "" ) printf "NO files found for target=${fileTarget}\n" ;;
   * ) printf "FileTarget Files found=${filesFound}\n" ;;


fileTarget="*.html"  # where I have some html docs in the current dir

FileTarget Files found=Baby21.html
charlie  22.html


NO files found for target=xorg-x11-fonts*

Note that this only works in the current directory, or where the var fileTarget includes the path you are want to inspect.

share|improve this answer
Your code will fail if fileTarget contains whitespace (e.g., fileTarget="my file*"). –  Richard Hansen Jun 17 '11 at 6:34
@RichardHansen what the solution when there is whitespace? –  Ross Mar 28 at 22:57
@Ross: Use the accepted answer: if ls "my file"* >/dev/null 2>&1; then ... –  Richard Hansen Mar 29 at 2:59
@RichardHansen thanks, sorry – not working for me. Have it fixed now . –  Ross Apr 2 at 9:44
@Ross, I've added an edit to mine that should work with files with spaces. Basically case "${filesFound}" in .... . Good luck to all. –  shellter Apr 2 at 11:23

I use this:

filescount=`ls xorg-x11-fonts* | awk 'END { print NR }'`  
if [ $filescount -gt 0 ]; then  
share|improve this answer

man test

if [ -e file ]; then

will work for dir\file.


share|improve this answer
This will not work with wildcards (which is what is asked in this question). If it matches more than one file you will get bash: [: too many arguments –  user000001 Apr 17 '13 at 13:28

Your Answer


