bash でプレフィックスを持つ 1 つ以上のファイルが存在するかどうかをテストするにはどうすればよいでしょうか? 例: [[-f foo*]]

bash でプレフィックスを持つ 1 つ以上のファイルが存在するかどうかをテストするにはどうすればよいでしょうか? 例: [[-f foo*]]

使用する方法はありますか?ファイル名の拡張以内test表現より具体的には、bash 条件式?

例えば:

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

...は出力します"いいえ!"foobarファイルが現在のディレクトリに存在するかどうか。

そして「varいいね!」を追加します...

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

...は出力します"それを見つけた!"ファイルが存在する場合foobar、ただし、展開echo $barによって返されたファイルが 1 つだけの場合のみです。

答え1

以下では、ブロック特殊ファイル、文字特殊ファイル、ディレクトリ、シンボリックリンクなど、どのファイルにも glob が一致するかどうかを気にしないことを前提としています。

これは次のような場合の理想的な使用例ですfailglob:

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

または、ファイルが存在する場合にそのリストが必要な場合:

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

ファイルが見つからないというエラーの場合は、次のように簡略化できます。

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

古い回答

lsこれはスクリプト内での(まれな!) 正当な使用法である可能性があります:

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

あるいは、find foo* -maxdepth 0 -printf ''.

答え2

に基づくこの答えshopt -s nullglobを使用すると、ディレクトリが空の場合に何も返されないことを保証できます。

[[ -n "$(shopt -s nullglob; echo foo*)" ]] && echo 'found it!' || echo 'nope!';

答え3

完全を期すために、 を使用した例をいくつか示します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

そしていくつかのテスト:

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

関連情報