0

Is there a way to use a Filename Expansion within a test expression, more specifically, a bash conditional expression?

For example:

[[ -f foo* ]] && echo 'found it!' || echo 'nope!';

... will output "nope!" either if the foobar file exists on the current directory or not.

And adding a var like...

bar=foo*
[[ -f `echo $bar` ]] && echo 'found it!' || echo 'nope!';

... will output "found it!" if the foobar file exists, but only if the echo $bar expansion returned only one file.

Ricardo
  • 111

3 Answers3

3

The following assume that you don't care whether the glob matches any files, including block special files, character special files, directories, symlinks, etc.

This is the ideal use case for failglob:

shopt -s failglob
if echo foo* &>/dev/null
then
    # files found
else
    # no files found
fi

Or, if you need the list of files if they exist:

shopt -s failglob
files=(foo*)
if [[ "${#files[@]}" -eq 0 ]]
then
    # no files found
else
    # files found
fi

If no files found is an error you could simplify this:

set -o errexit
shopt -s failglob
files=(foo*)
# We know that the expansion succeeded if we reach this line

Old answer

This might be a (rare!) legitimate use of ls in a script:

if ls foo* &>/dev/null
then
    …
else
    …
fi

Alternatively, find foo* -maxdepth 0 -printf ''.

l0b0
  • 51,350
0

Based on this answer, we can use shopt -s nullglob to ensure noting is returned if the directory is empty:

[[ -n "$(shopt -s nullglob; echo foo*)" ]] && echo 'found it!' || echo 'nope!';
Ricardo
  • 111
  • 1
    You shouldn't use && and ||, just use an if construct, it's also not necessary to terminate the line with ; – jesse_b Aug 13 '20 at 22:35
  • This does not seem to capture the fact that the question uses -f and not -e as the test operator. The test should be for regular files, not for existence. – Kusalananda Aug 14 '20 at 05:42
0

For completeness' sake, here are some examples using find:

#!/bin/bash

term=$1

if find -maxdepth 1 -type f -name "$term*" -print -quit | grep -q .; then echo "found" else echo "not found" fi

if [ -n "$(find -maxdepth 1 -type f -name "$term*" -print -quit)" ]; then echo "found" else echo "not found" fi

And some tests:

user@host > find -type f
./foobar
./bar/foo
./bar/bar
./find_prefixed_files.sh
./ba
user@host > ./find_prefixed_files.sh foo
found
found
user@host > ./find_prefixed_files.sh bar
not found
not found