web-dev-qa-db-ja.com

forループの場合のネスト

私はbashスクリプトを初めて使用するので、これはおそらく愚かな構文エラーですが、なぜこのコードが機能しないのですか?

for x in $(ls)
do
  if [ -d $x ]
  then
  echo $x
  fi
done

Forセクションとifセクションは別々に動作しますが、出力は生成されません。

21
James Jenkinson

2つのこと。 lsを使用してファイルを反復したり、パラメーター展開を引用符で囲む_"$x"_を使用したりしないでください。 forおよびif構文自体は正しいです。私はdothenを同じ行に置くことを好みます

_for file in *; do
    if [[ -d "$file" ]]; then
        echo "$file is a directory"
    Elif [[ -f "$file" ]]; then
        echo "$file is a regular file"
    fi
done
_

Bashを学習するには、 http://mywiki.wooledge.org/BashGuide を読むことをお勧めします。他のほとんどのチュートリアルとガイドは、残念ながらあまり良くありません。

ファイルを反復するためにfor x in $(ls)を行わない理由は、forwordsおよびlsを反復するためです。ファイル名付きの行を出力します。それらのファイル名に空白が含まれている場合、それらのファイル名はさらに単語に分割されるため、ファイル名のwordsではなく、ファイル名。明らかに、動作する単純なケースではありますが、すべてのケースを処理するより短くよりエレガントな方法があるのに、なぜ半分動作するソリューションを使用するのでしょうか?

_for x in *_を使用すると、シェルは_*_を現在のディレクトリ内のそのパターンに一致するすべてのファイル名(パス名展開と呼ばれる)に置き換えます。各ファイル名は個別のWordであるため、ファイル名に含まれる文字。ファイル名には、_/_およびNULバイト(\ 0)を除く、任意の文字(改行を含む)を含めることができます。

http://mywiki.wooledge.org/ParsingLs を参照してください。

_[[_ vs _[_の使用に関して。 _[_は、bourne Shellから継承されたコマンドで、文字列、ファイル、および数値をテストするために使用されます。 Bashは、より強力な_[[_キーワードを追加して、_[_をはじめとするすべてを実行できます。 shスクリプトを記述する場合は、_[_を使用する必要がありますが、bashスクリプトでは、より強力な_[[_および_((_構文を使用する必要があります。 _[_と_[[_の違いの詳細については、 http://mywiki.wooledge.org/BashFAQ/031 を参照してください。

24
geirha

ステートメントのさまざまな部分を分離するために使用されている文字に問題があるのでしょうか?

試した場合:

for x in $(ls); do if [ -d $x ]; then echo $x; fi; done

それは出力を生成しますか?

5
imm

1)構文は完全に合法です

2)はい、「if/else」ブロックをループ内にネストできます。外部ループ内に内部ループをネストすることもできます:)

3)「if [-d $ x]」は、「x」が「ディレクトリ」であるかどうかを確認します。

出力が表示されない場合、おそらくサブディレクトリはありませんか?

提案:

  • ターミナルウィンドウを開く

  • スクリプトを実行します。出力を取得するかどうかを確認します。

  • そうでない場合は、mkdir moose。これにより、(偶然ではないが)「ムース」と呼ばれるサブディレクトリが作成されます。

  • スクリプトを再実行します。 少なくとも "moose"が表示されるはずです。

1
paulsm4