如果我想检查单个文件是否存在,我可以使用test -e filename或[-e filename]进行测试。

假设我有一个glob,我想知道是否有文件名与glob匹配的文件存在。glob可以匹配0个文件(在这种情况下,我不需要做任何事情),也可以匹配1个或多个文件(在这种情况下,我需要做一些事情)。我如何测试一个glob是否有任何匹配?(我不在乎有多少匹配,这将是最好的,如果我能做到这一点与一个if语句和没有循环(只是因为我发现最易读)。

(如果glob匹配多个文件,则test -e glob*失败。)


当前回答

我还有另一个解决方案:

if [ "$(echo glob*)" != 'glob*' ]

这对我来说很有用。我可能漏掉了一些极端情况。

其他回答

在Bash中是这样的(测试文件包含模式):

shopt -s nullglob
compgen -W *pattern* &>/dev/null
case $? in
    0) echo "only one file match" ;;
    1) echo "more than one file match" ;;
    2) echo "no file match" ;;
esac

它比compgen -G好得多:因为我们可以区分更多的情况,更精确。

它只能使用一个通配符*。

#!/bin/bash
set nullglob
touch /tmp/foo1 /tmp/foo2 /tmp/foo3
FOUND=0
for FILE in /tmp/foo*
do
    FOUND=$((${FOUND} + 1))
done
if [ ${FOUND} -gt 0 ]; then
    echo "I found ${FOUND} matches"
else
    echo "No matches found"
fi
#!/usr/bin/env bash

# If it is set, then an unmatched glob is swept away entirely -- 
# replaced with a set of zero words -- 
# instead of remaining in place as a single word.
shopt -s nullglob

M=(*px)

if [ "${#M[*]}" -ge 1 ]; then
    echo "${#M[*]} matches."
else
    echo "No such files."
fi

nullglob和compgen都只在一些bash shell上有用。

在大多数shell上工作的(非递归)解决方案是:

set -- ./glob*                  # or /path/dir/glob*
[ -f "$1" ] || shift            # remove the glob if present.
if    [ "$#" -lt 1 ]
then  echo "at least one file found"
fi

这招似乎很管用:

#!/usr/bin/env bash
shopt -s nullglob
if [ "`echo *py`" != "" ]; then
    echo "Glob matched"
else
    echo "Glob did not match"
fi

它可能需要bash,而不是sh。

这是因为如果没有匹配项,nullglob选项会导致glob计算为空字符串。因此,echo命令的任何非空输出都表明glob匹配了某些内容。