.png
.txt
次のファイル形式のいずれかがディレクトリに存在するかどうかを検出したいと思います.tar.gz
。
次のいずれかをテストしたときに正しく機能しました。
shopt -s nullglob
MYDIR=/some_dir
if [ $MYDIR/*.png] && [ $MYDIR/*.txt]; then
echo "All files present"
else
echo "At least one type is missing"
fi
しかし、次のように3つすべてをテストしようとすると
if [ $MYDIR/*.png] && [ $MYDIR/*.txt] && [ $MYDIR/*.tar.gz]; then
...
または使用
if [[ $MYDIR/*.png && $MYDIR/*.txt && $MYDIR/*.tar.gz ]]; then
...
まあ、正しい動作は発生しません(ファイルのいずれかが欠落している場合でもまだtrueを返します)。
ここで何が起こっているのでしょうか?
答え1
ファイル名のワイルドカードパターンが一致するかどうかをテストすることはできません(そして、[ ... ]
すべてのテストで最後のスペースの前にスペースがありません。コードが機能しません)。]
[ ... ]
方法は、一致を実行し、一致する名前の数を数えることです。
shopt -s nullglob # make globs expand to nothing if they don't match
shopt -s dotglob # also match hidden names
error=false
for ext in png txt tar.gz; do
set -- "$MYDIR"/*."$ext"
if [ "$#" -eq 0 ]; then
printf 'Nothing matches "%s"\n' "$MYDIR/*.$ext" >&2
error=true
break # possibly, unless you want the user to see all patterns that fail
fi
done
if "$error"; then
echo 'Can not continue' >&2
exit 1
fi
より多くを入力したい場合、または既存の位置引数のリストを保持したい場合は、名前付き配列を使用できます。set --
行をnames=( "$MYDIR"/*."$ext" )
および"$#"
に変更します"${#names[@]}"
。すべての引用符が重要です。
答え2
必ず以下を使用してください。
shopt -s nullglob
文字通りテストする前に偽の肯定を避けてください$MYDIR/*.png
。
ただし、Bashテストではこのようなワイルドカードをテストできず、配列をテストする必要があります。
txt=( *.txt ) tgz=( *.tar.gz ) png=( *.png )
if [[ ${txt[@]} && ${png[@]} && ${tgz[@]} ]]; then
echo SUCCESS
fi
ハッキングを使用してワイルドカードがあるかどうかをテストする別の方法は次のとおりですcompgen
。
cd "$workdir"
if (compgen -W *.txt && compgen -W *.png && compgen -W *.tar.gz) &>/dev/null; then
echo 'SUCCESS'
else
echo >&2 'At least one filetype missed'
fi
bash shebangを追加することを忘れないでください:
#!/bin/bash
または
#!/usr/bin/env bash
[[
[
コマンドに似ていますが、より強力なbashキーワードです。バラよりhttp://mywiki.wooledge.org/BashFAQ/031そしてhttp://mywiki.wooledge.org/BashGuide/TestsAndConditionals。 POSIX shに文章を書くのではないならオススメです。[[
使用例:
[[ ${names[@]} ]] && echo 'SUCCESS'
あなたがしようとしているように、発生回数を数える必要はありません。