Windows 10 Anniversary UpdateからサポートしたWSL(Windows Subsystem for Linux)。その結果としてWindows 10上でもBUW(Bash on Ubuntu on Windows)が動作し、各種Linuxコマンドが利用可能になった。本連載ではWSLに関する情報や、Bashから実行するシェルスクリプトを紹介する。

オプションでファイル名 or 拡張子を小文字化する

さて、前回予告したように前々回のシェルスクリプトを結合して、コードの最適化を行おう。まずは以下のシェルスクリプトを任意のテキストエディターにコピー&ペーストし、chmodコマンドで実行モードを付与してから、シェルスクリプトを実行してほしい。

 #!/bin/bash

 CMDNAME=`basename $0`
 IFS_Backup=$IFS
 IFS=$'\n'

 function usage() {
    echo "Usage: $CMDNAME [オプション] [対象ディレクトリ]"
    echo ""
    echo "-e    拡張子を小文字化"
    echo "-f    ファイル名を小文字化"
    exit 1
 }

 while getopts :e:f: Option
 do
    case $Option in
        e )
            if [ -z "$OPTARG" ]; then
                echo usage;
            fi
            Flag_E="TRUE"
            ;;
        f )
            if [ -z "$OPTARG" ]; then
                echo usage;
            fi
            Flag_F="TRUE"
            ;;
        \?* )
            usage ;;
    esac
 done

 if [ -e $2 ]; then
    for FName in $(find $2 -type f); do
        if [ -f ${FName} ]; then
            Directory=`dirname ${FName}`
            FileName=`basename ${FName%.*}`
            FileExt="${FName##*.}"

            if [ "$Flag_F" = "TRUE" ]; then
                case "$FileName" in
                    [a-zA-Z0-9]* )
                        NewFName1=`echo ${FileName} | tr 'A-Z' 'a-z'`
                        NewFName2=`echo ${FileName^}`
                        echo ${NewFName^}
                        Src="${Directory}/$FileName.$FileExt"
                        Dst="$Directory/$NewFName2.$FileExt"
                        mv ${Src} ${Dst} 2>/dev/null
                        echo "ファイル名を $Dst へ変更しました."
                        ;;
                    [!a-zA-Z0-9]* )
                        echo ${FileName,,}
                        NewFName2=`echo ${FileName,,}`
                        Src="${Directory}/$FileName.$FileExt"
                        Dst="$Directory/$NewFName2.$FileExt"
                        mv ${Src} ${Dst} 2>/dev/null
                        echo "ファイル名を $Dst へ変更しました."
                        ;;
                    * )
                        ;;
                esac
            elif [ "$Flag_E" = "TRUE" ]; then
                NewExt=`echo ${FileExt} | tr 'A-Z' 'a-z'`
                Src="${Directory}/$FileName.$FileExt"
                Dst="$Directory/$FileName.$NewExt"
                mv ${Src} ${Dst} 2>/dev/null
                echo "拡張子を $Dst へ変更しました."
            else
                usage
            fi
        fi
    done
 else
    usage
 fi

 IFS=$IFS_Backup

それではシェルスクリプトの内容を説明しよう。8行~13行目におけるヘルプメッセージのファンクション化や、15~33行目で処理している「getopts」を用いた引数の処理は以前のシェルスクリプトでも紹介したので割愛する。35行目のif文はシェルスクリプトの2つ目の引数が実際に存在するディレクトリ(フォルダー)なのか判断し、37行目のfor文で処理を実行する仕組みだ。処理対象とするファイル名の取得を「ls」コマンドに置き換えようかと試してみたが、カレントディレクトリの移動が煩雑になるため、「find」コマンドのままにしている。

そのままシェルスクリプトを実行すると、ヘルプメッセージが現れる

38~40行目は取得したファイル名などを、ディレクトリやファイル名、拡張子に分解し、42~63行目はオプション「-f」を付けた時のファイル名変更処理。64~69行目はオプション「-e」を付けた時の拡張子変更処理となる。内容自体は前回・前々回と同じなので説明は不要だろう。

オプション「-f」と対象となるディレクトリを指定すると、ファイル名の小文字化が行われる

今回ファイル名もしくは拡張子を変更するコマンドとして、「mv」から「rename」に変更しようと思ったが、renameはPerlスクリプトのため、処理に要する時間は短縮されなかった。そのため、そのままmvコマンドを使用している。

オプション「-e」と対象となるディレクトリを指定すると、拡張子の小文字化が行われる

阿久津良和(Cactus)