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

Haskellも動作するBUW/WSL

Microsoftは開発言語「Haskell」がBUW/WSL上で動作することを、公式ブログで報告している。筆者はHaskellの存在を寡聞にして知らなかったが、一部のユーザー間で根強い人気を持つ開発言語だと言う。記事によれば、Windows 10 Insider Preview ビルド14986からサポートを開始しており、同環境では実際に試せるようなので、筆者も記事を参考にHaskell用コードのコンパイル・実行を試してみた。

「sudo apt-get install ghc -y」を実行して、事前にHaskellのパッケージをインストールする

ブログ記事の説明どおり、任意のテキストエディターで簡単なコードを記述する

コンパイルは「ghc」コマンドを利用する

こちらがコンパイル後の状態。インターフェースファイル(hello.hi)とオブジェクトファイル(hello.o)が確認できる

こちらは実行結果。コードの内容どおり「Hello World!」が表示された

ご覧のとおり拍子抜けするほど簡単に動作し、Windows 10 Creators Updateローンチ以降は、Haskell利用者の選択肢にWindows 10も含まれることとなる。Microsoftは開発者に対して「好みの環境と慣れた言語で開発できる」とWindows 10をアピールし、OSS(オープンソースソフトウェア)の取り組みに注力している。確かに実機で動作するLinuxディストリビューションと比較した場合、WSLは完成したとは言いがたい。

だが、既報のとおり、2017年3月7日(現地時間)にローンチ予定のVisual Studio 2017では、GNUデバッガを利用したLinux用開発環境を実現するなど、開発環境を整えつつある。開発者向け機能であるWSLは今後も粛々と完成度を高めていくだろう。

ファイル名の頭文字を大文字、それ以外を小文字にする

さて、前回は異なるファイルの拡張子を小文字に変換するシェルスクリプトを紹介した。そこで気になったのがファイル名側のルールだ。大文字・小文字は単語の中で混在するのが当たり前だが、文頭や固有名詞は頭文字、それ以外は小文字を用いるのが通例である。もちろん強調単語をすべて大文字にする注意喚起文など例外もあるが、我々がファイル名を付ける場合、意識しているだろうか。

ファイル名に限った話ではないが、コード記述時と同じように一定のルールに即した命名規則を普段から身に付けておきたい。そこで作成したのが以下のシェルスクリプトである。ファイル名の頭文字のみ大文字化し、それ以外は小文字化。日本語と英字が混在している場合は頭文字を除いて小文字化する。いつもどおり任意のテキストエディターで、下図に示したコードをコピー&ペーストした後に、chmodコマンドで実行モードを付与してから、シェルスクリプトを実行してほしい。

 #!/bin/bash

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

 if [ $# -ne 1 ]; then
    echo "Usage: $CMDNAME Directory" 1>&2
    exit 1
 else
    for FName in $(find $1); do
        if [ -f ${FName} ] ; then
            Directory=`dirname ${FName}`
            FileName=`basename ${FName%.*}`
            FileExt="${FName##*.}"
            case "$FileName" in
                [a-zA-Z0-9]* )
                    NewFName1=`echo ${FileName} | tr 'A-Z' 'a-z'`
                    NewFName2=`echo ${FileName^}`
                    Src="${Directory}/$FileName.$FileExt"
                    Dst="$Directory/$NewFName2.$FileExt"
                    mv ${Src} ${Dst} 2>/dev/null
                    echo "$Src -> $Dst へ変更しました."
                    ;;
                [!a-zA-Z0-9]* )
                    NewFName2=`echo ${FileName,,}`
                    Src="${Directory}/$FileName.$FileExt"
                    Dst="$Directory/$NewFName2.$FileExt"
                    mv ${Src} ${Dst} 2>/dev/null
                    echo "$Src -> $Dst へ変更しました."
                    ;;
                * )
                    ;;
            esac
        fi
    done
 fi
 IFS=$IFS_Backup

それではシェルスクリプトの内容を説明しよう。今回は英数字で構成されたファイル名か否かを16~34行目のcase文で分岐させ、英数字の場合は18行目で1度すべて小文字化し、19行目で頭文字のみ大文字化させている。さらに日本語が含まれる場合(英数字以外)は26行目で全体を小文字化させ、前回同様mvコマンドでファイル名を変更する仕組みだ。

スクリプトを実行した状態。echoコマンドの出力結果どおり、ファイル名の頭文字のみ大文字化する

ここでポイントとなるのが、Bashバージョン4から利用可能になった変数展開時の構文だ。詳しくは下図に示した表をご覧頂きたいが、キャレット(^)やカンマ(,)を使うことで値の文字列を大文字化・小文字化するというもの。今回はtrコマンドをそのまま残しているが、この構文を使えば容易に文字列の操作が可能になる。

文字列の大文字・小文字操作を行う変数展開

次回は今回と前回のシェルスクリプトを結合し、コードの最適化を行おう。

こちらはシェルスクリプト前の状態

シェルスクリプトを実行すると頭文字のみ大文字となる

阿久津良和(Cactus)