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"
fi
I have also tried it without the double quotes.
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.
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
break
done
This is very similar to @grok12's answer, but it avoids the unnecessary iteration through the whole list.
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.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.@CostiCiudatu have you checked how that alternative works when there are spaces in the directory name? Wouldn't e.g.
for f in /path/to/your files*
interpreted as two arguments,/path/to/your
andfiles*
? I've tried putting double-quotes around, but that didn't work out (never finds a file, even if there's one).@Izzy, you are supposed to put that in double quotes, but leave the
*
outside:for f in "/path/to/your files"*
should work.Warning. This will fail if the directory contains a lot of files. The expansion of "*" will exceed the command line length limit.