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

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

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


当前回答

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

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

然后,如果需要对文件做些什么,就可以遍历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

基于flabdablet的答案,对我来说,它看起来最简单的(不一定是最快的)就是使用find本身,同时在shell上留下glob展开,像:

find /some/{p,long-p}ath/with/*globs* -quit &> /dev/null && echo "MATCH"

或者在if like中:

if find $yourGlob -quit &> /dev/null; then
    echo "MATCH"
else
    echo "NOT-FOUND"
fi
(ls glob* &>/dev/null && echo Files found) || echo No file found

Bash-specific解决方案:

compgen -G "<glob-pattern>"

转义模式,否则它将被预先展开为匹配。

退出状态为:

1表示不匹配, 0表示“一个或多个匹配”

Stdout是匹配glob的文件列表。 我认为这是最好的选择,就简洁和最小化潜在的副作用而言。

例子:

if compgen -G "/tmp/someFiles*" > /dev/null; then
    echo "Some files exist."
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