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

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

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


当前回答

如果你有globfail集,你可以使用这个疯狂的(你真的不应该)

shopt -s failglob # exit if * does not match 
( : * ) && echo 0 || echo 1

or

q=( * ) && echo 0 || echo 1

其他回答

if ls -d $glob > /dev/null 2>&1; then
  echo Found.
else
  echo Not found.
fi

请注意,如果有很多匹配或文件访问缓慢,这可能会非常耗时。

我喜欢

exists() {
    [ -e "$1" ]
}

if exists glob*; then
    echo found
else
    echo not found
fi

这既可读又有效(除非有大量的文件)。 主要的缺点是它比看起来要微妙得多,有时我觉得有必要添加一个很长的评论。 如果有匹配项,shell将展开“glob*”,并将所有匹配项传递给exists(),后者检查第一个匹配项并忽略其余匹配项。 如果没有匹配,则将"glob*"传递给exists()并发现它也不存在。

编辑:可能是假阳性,见评论

#!/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

假设你可能想对文件做些什么,如果它们存在:

mapfile -t exists < <(find "$dirName" -type f -iname '*.zip'); [[ ${#exists} -ne 0 ]] && { echo "Zip files found" ; } || { echo "Zip files not found" ; }

然后,如果需要对文件做些什么,就可以遍历exists数组。

(ls glob* &>/dev/null && echo Files found) || echo No file found