3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

zsh環境でfindコマンドのforループが思ったように回らない事件

Last updated at Posted at 2022-11-03

zsh環境でシェルスクリプトでforループを書くとき、ある点に注意しないと予期しない動作になります。結構ハマる箇所だと思ったので注意点をメモしておきます。

※なお、bash環境では修正前のやり方でも問題なく動くようです(ご指摘ありがとうございます!)。

findコマンドを使うと、特定の名前のディレクトリやファイルをリストアップすることができます。

jpgファイルをリストアップするコマンド
find . -name "*.jpg" -type f

とすれば、カレントディレクトリ内の.jpg拡張子を持つファイルのリストを取得することができます。例えば今、このコマンドの出力が以下のようであったとします。

上記コマンドを実行した結果
./image-5.jpg
./image-2.jpg
./image-0.jpg
./image-4.jpg
./image-6.jpg
./image-9.jpg
./image-8.jpg
./image-1.jpg
./image-3.jpg
./image-10.jpg
./image-7.jpg

さて、これをfor文で回してみましょう(以下のコードは失敗例)。

for文で結果をループ(失敗例)
files=`find . -name "*.jpg" -type f`
for file in $files; do
    echo $file
done
出力結果
./image-5.jpg
./image-2.jpg
./image-0.jpg
./image-4.jpg
./image-6.jpg
./image-9.jpg
./image-8.jpg
./image-1.jpg
./image-3.jpg
./image-10.jpg
./image-7.jpg

できてそうな気がしますよね。でも、本当かな?

echo $fileのあとにecho "---------"と区切りを入れてみましょう。

for文で結果をループ(失敗例の挙動確認)
files=`find . -name "*.jpg" -type f`
for file in $files; do
    echo $file
    echo "---------"
done
出力結果
./image-5.jpg
./image-2.jpg
./image-0.jpg
./image-4.jpg
./image-6.jpg
./image-9.jpg
./image-8.jpg
./image-1.jpg
./image-3.jpg
./image-10.jpg
./image-7.jpg
---------

区切り文字列が最後にしか出力されていませんね。forループは1回しか走っていないようです。

では、どうしたらいいのか。答えは簡単です。
外側に丸括弧をつければ、リストとして認識され意図していた通りの挙動になります。

()で囲ってリストにする
files=(`find . -name "*.jpg" -type f`)
./image-5.jpg
---------
./image-2.jpg
---------
./image-0.jpg
---------
./image-4.jpg
---------
./image-6.jpg
---------
./image-9.jpg
---------
./image-8.jpg
---------
./image-1.jpg
---------
./image-3.jpg
---------
./image-10.jpg
---------
./image-7.jpg
---------

正しく反復できていますね。

3
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?