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

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

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


当前回答

Bash-specific解决方案:

compgen -G "<glob-pattern>"

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

退出状态为:

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

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

例子:

if compgen -G "/tmp/someFiles*" > /dev/null; then
    echo "Some files exist."
fi

其他回答

ls | grep - q“glob *。”

这不是最有效的解决方案(如果目录中有大量文件,它可能会比较慢),但它很简单,易于阅读,而且它的优点是正则表达式比普通的Bash glob模式更强大。

if ls -d $glob > /dev/null 2>&1; then
  echo Found.
else
  echo Not 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
[ `ls glob* 2>/dev/null | head -n 1` ] && echo true

在Bash中,你可以glob到数组;如果glob不匹配,你的数组将包含一个与现有文件不对应的条目:

#!/bin/bash

shellglob='*.sh'

scripts=($shellglob)

if [ -e "${scripts[0]}" ]
then stat "${scripts[@]}"
fi

注意:如果你设置了nullglob, scripts将是一个空数组,你应该使用["${scripts[*]}"]或["${#scripts[*]}" != 0]来测试。如果您正在编写一个必须使用或不使用nullglob的库,那么您将需要

if [ "${scripts[*]}" ] && [ -e "${scripts[0]}" ]

这种方法的一个优点是,这样您就有了想要处理的文件列表,而不必重复glob操作。