eijenson Con

主に作業中にはまったことの作業ログを書いていきます。

shellでフォルダ内の全てのファイルに対してfor処理をする

目的

screenshot
├── スクリーンショット10月
│   └── 01.png
│   ├── 02.png
│   ├── 03.png
│   ├── 04.png
│   ├── 05.png
│   ├── 06.png
│   ├── 07.png
│   └── 08.png
└── スクリーンショット11月
    └── 01.png
    ├── 02.png
    ├── 03.png
    ├── 04.png
    ├── 05.png
    ├── 06.png
    ├── 07.png
    └── 08.png

こんな感じのディレクトリ構成になっていて、各フォルダ内の全ての画像をjpgに変えたかった

作成したshell

#!/bin/bash
#set -eux

while read -d $'\0' d; do
    dir=`basename "${d}"`
    echo dir="${dir}" 
    while read -d $'\0' file; do
        echo file="${file}" 
        convert "${file}" -quality 100 "${file}"
    done < <(find "$dir" -mindepth 1 -maxdepth 1 -print0)
done < <(find . -type d -mindepth 1 -maxdepth 1 -print0)

説明

while read -d $'\0' d; do
  #今いる場所のフォルダ分loopを回す
 # ${d}でフォルダのpathが取れる
done < <(find . -type d -mindepth 1 -maxdepth 1 -print0)

while read -d $'\0' d; do は正直良くわかっていないが、いろいろ試した結果ディレクトリ内のすべてのファイルをループする - Qiitaの記事で書かれているやり方が一番良く動いたので使っている

done < <(find . -type d -mindepth 1 -maxdepth 1 -print0)

find . で今いる場所を検索する

-type d でディレクトリのみに検索範囲を指定

-mindepth 1 -maxdepth 1 で今いるディレクトリのみを検索範囲にする(深く探さない)

-print0 で空白文字を含むディレクトリも検索できるようにする参考URL→findとxargsコマンドで-print0オプションを使う理由(改) - Qiita

中身のloop

 dir=`basename "${d}"`
    echo dir="${dir}" 
    while read -d $'\0' file; do
        echo file="${file}" 
        convert "${file}" -quality 100 "${file}"
    done < <(find "$dir" -mindepth 1 -maxdepth 1 -print0)

dir=`basename "${d}"` ディレクトリパスからディレクトリ名を取得している

done < <(find "$dir" -mindepth 1 -maxdepth 1 -print0) で-type d をなくしてloopを回しているため、ファイルも検索対象になっている

ファイルは画像のみなので、convert "${file}" -quality 100 "${file}"ImageMagickのconvertコマンドを叩いて変換ができる