人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

シェルスクリプトのファイル存在判定でワイルドカードを使いたい


ファイル判定で以下のように書くと
「unexpected operator」とエラーになります。

if [ -f /path/*.txt ]; then
echo "OK"
fi


以下のように書けばエラーにならない
if [ -f /path/hoge.txt ]; then
echo "OK"
fi

ワイルドカードを使って1つもファイルがないか、あるいは1つでもファイルがあるかを判定したいのですが、
どう書いたら良いでしょうか。

●質問者: spacewarp
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● JULY
●68ポイント ベストアンサー

ワイルドカードが先に展開されて test コマンド(if [ ? の "[" の実体)の引数になってしまうので、期待した動作にならないはずです。

sh -x スクリプトファイル名

とすれば、その様子が分かると思います。

で、単純に ls コマンドの戻り値を使う方法が考えられます。

ls /path/*.txt >/dev/null 2>&1
if [ $? -ne 0 ]; then
 echo "No match"
else
 echo "At least one file"
fi

a-kuma3さんのコメント
コマンドの戻り値を使う場合には、普通、こう書きます。 >|sh| if ls path/*.log > /dev/null 2>&1 then echo "OK" else echo "NG" fi ||< # 説明のために、敢えて冗長に書いたのであれば失礼をご勘弁

spacewarpさんのコメント
おお、スマートな方法ですね。参考になります

2 ● a-kuma3
●66ポイント

ファイルとディレクトリを判定したいとか、読み込み可能か、など test コマンドのパラメータをフルに使いたければ、シェルの関数を書いてあげる感じになります。

#引数で指定されたファイルがあるかどうかを確認する関数

is_file_exist() {
 for f in $*
 do
 if [ -f $f ]
 then
 return 0
 fi
 done
 return 1
}


# こうやって使います

if is_file_exist path/*.txt
then
 echo "OK : txt"
else
 echo "NG : txt"
fi

# 使う方で [] がないのは、間違いじゃないですよ :-)


spacewarpさんのコメント
ループで取ればいいんですね。なるほど

3 ● richmikan
●66ポイント

ワイルドカードは、該当ファイルが存在すれば元の文字列が変化しますが、存在しなければ元の文字列そのままになるので、AWKを使って文字列が変化した(=該当ファイルがあった)ら"OK"を表示する、というスクリプトを書いてみました。

echo /path/*.txt | awk '$0!="/path/*.txt"{print "OK";}'

ちなみに、AWKの動作をprintではなくてexitにすれば後のシェルスクリプトで分岐させることもできます。

(a)case文で

echo /path/*.txt | awk '{exit ($0!="/path/*.txt")?0:1;}'
case $? in
 0) echo "OK";;
 *) echo "NG";;
esac

(b)if文で

echo /path/*.txt | awk '{exit ($0!="/path/*.txt")?0:1;}'
if [ $? -eq 0 ]; then
 echo "OK"
else
 echo "NG"
fi

spacewarpさんのコメント
いろんな書き方がありますね。 ありがとうございます。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ