2

特定のタイプのファイルの数を見つけようとしています。ファイルが存在する場合、このスクリプトは正常に動作し、そうでない場合は for ループが 1 回実行されます (これは実行されるとは想定されていません)。

echo "Checking for text files..."

j=0
for i in *.txt;
do
echo $i;
j=`expr $j + 1`;
done

if [ $j -ge 0 ];then
echo "No.of Text files:"$j
else
echo "No Text files."
fi

のように同じことをする別の方法があるかもしれませんls *.txt |xargs ...。しかし、初心者として、投稿されたスクリプトの問題を知りたいです。この点について、あなたの知識を共有していただきたいと思います。

4

2 に答える 2

5

スクリプトに問題はありませんが、最新のビルトインを使用してより良いスタイルで記述できることと、テキスト ファイルがない場合に失敗することを除いては、以下を参照してください。

echo "Checking for text files..."

j=0
for i in *.txt; do
    echo "$i"
    ((++j))
done

if ((j!=0)); then
    echo "No. of Text files: $j"
else
    echo "No Text files."
fi

グロビングを使用する場合は、常にいずれかを使用するnullglobことをお勧めしますfailglob

  • failglobグロブを展開できない場合はエラーが発生します。
  • nullglob適切な拡張がない場合は、何も拡張されません。

これらがないと、適切な展開がない場合に (verbatim)*.txtに展開され*.txtます。これはまさに回避したいことです!

あなたの場合、ちょうど置く

shopt -s nullglob

をスクリプトの先頭に追加すれば完了です。

*.txtファイルの数を数える方法としては、次のようなものがあります。

shopt -s nullglob
a=(*.txt)
echo "There are ${#a[@]} text files"

この大騒ぎは何nullglobですかfailglob

スクラッチディレクトリに行きましょう:

$ mkdir scratch; cd scratch
$ # this dir is empty
$ echo *.txt
*.txt
$ 

グロブには適切な展開がないためです。今:

$ shopt -s nullglob
$ echo *.txt

$ 

のためnullglob。次に、設定を解除nullglobして設定しfailglobます。

$ shopt -u nullglob
$ shopt -s failglob
$ echo *.txt
bash: no match: *.txt
$

それを得る?

要点は次のとおりです。bash でを使用するたびに、またはを使用してスクリプトをより堅牢にします。failglobnullglob

頬の要点の舌として:またはなしでグロビングを使用するたびに、神は子猫を殺します。failglobnullglob

shoptおよびシェルのオプションの動作に関する詳細が必要な場合は、マニュアルの The Shopt Builtin セクションを参照してください。

于 2013-06-29T12:50:11.030 に答える
1

パターン*.txtに一致するファイルがない場合は、リテラル文字列として解釈されます"*.txt"。そのため、ループは少なくとも 1 回実行されます。

この問題に対処するには、いくつかの方法があります。次のように、一致するファイルの存在のチェックを追加できます。

if ls *.txt >/dev/null 2>&1; then
  for i in *.txt; do
    ...
  done
fi

ループ内で何をしたいかによっては、以下を使用することもできますfind

find . -maxdepth 1 -name "*.txt" | while read i; do
  ...
done

ただし、ループはサブシェルで実行され、サブシェルが終了すると (つまり、ループが終了すると)へのすべての変更が失われる$jため、この構造では機能しないものもあります ( incrementing など)。while$j

補足として: の増分を$jからj=`expr $j + 1`に変更します((j++))

于 2013-06-29T12:48:54.827 に答える