拡張されていないアスタリスクによるエラーの防止

拡張されていないアスタリスクによるエラーの防止

Bashでは、以下のようにforループを頻繁に使用します。

for file in *.type; do 
  sommecommand "$file"; 
done;

一致するすべてのファイルに対して操作を実行します*.type。この末尾のファイルが作業ディレクトリにない場合、アスタリスクは拡張されず、通常は一部のコマンドでファイルが見つからないというエラーメッセージが表示されます。私はこの間違いを避けるためのいくつかの方法をすぐに思い出すことができます。しかし、条件を追加することはあまりエレガントに見えません。これを達成するための短くてきれいな方法はありますか?

答え1

はい、次のコマンドを実行します。

shopt -s nullglob

一致が無効になり、エラーは発生しません。

  • デフォルトでこの動作が必要な場合は、~/.bashrc
  • POSIX シェルで空のグローブを検出するには、次のようにします。

    for i in *.txt; do
      [ "$i" = '*.txt' ] && [ ! -e '*.txt' ] && continue
    done
    

バラよりhttp://mywiki.wooledge.org/NullGlob

答え2

shopt -s nullglobBashでは、一致するものがない場合は空の配列として拡張を使用できます。

なしのPOSIXシェルでは、hasをループの最初の部分としてnullglob使用して、渡されたファイル名が実際に存在することを確認することでこの問題を回避できます。[ -e "$file" ] || [ -L "$file" ] || continuefor

答え3

オプションのないシェルの場合、一般的な技術nullglobは次のとおりです。

set -- [*].type *.type
case $1$2 in
  '[*].type*.type') shift 2;;
  *) shift
esac
for file do
  cmd  -- "$file"
done

追加の内容は、[*].type現在のディレクトリでファイル呼び出しを処理することです。*.type

今ドットファイルを含めるにはこれはもっと複雑になる

私はこの技術が数年前にUsenetでLaura Fairheadによって作られたと信じています。

答え4

find . -name '*.type' -maxdepth 0 -exec somecommand "{}" ";"

これにより、for方程式からループとシェルのワイルドカードが完全に削除されます。コマンドは一致する項目ごとに 1 回ずつfind実行され、-exec一致する項目がないと実行されません。指定されたパス引数のサブディレクトリ(この場合)-maxdepth 0に再帰しないようにfindに指示します。.

欠点は、このアプリケーションがほとんどすべてのLinuxシステム(そしておそらくほとんどのUnixでも)に存在しますが、他のアプリケーションに関連していることです。

関連情報