FSLユーザーのためのシェルスクリプトチュートリアル

FSLを開発しているFMRIBグループは、FSL courseのスライドおよびデータセットを公開してくださっています。ここで勉強しているときに、さりげなくシェルスクリプトのチュートリアルもあることが気になっていました。

先日、時間をとってこのチュートリアルを丁寧に見ていったところ、非常に勉強になることが多く、シェルスクリプトの理解が深まりました。FSLユーザーのみならず、脳画像解析でUNIX系のOS(Macも含む)を使う方々にとって有益な情報が多いと思いましたので、日本語にしておきたいと思い、FMRIBのSteve Smith教授の承諾を得て、このチュートリアルを翻訳させていただきました。

オリジナルのサイト自体は、スライド形式になっており、レクチャーと演習部分にわかれています。しかし、翻訳していく段階でこれを完全に模倣するよりは、レクチャーと演習をそれぞれ別の媒体として準備するのも勉強するのには都合がいいかもと考え、それぞれ別のPDFを準備しました。

関心のある方は、以下のリンクからPDFをご覧いただけたらと思います。

FSL course: シェルスクリプト
FSL course: シェルスクリプト演習

Print Friendly, PDF & Email

4 thoughts on “FSLユーザーのためのシェルスクリプトチュートリアル

  1. 私は精神科医で脳画像研究をしているものです。
    script、downloadなど日本語で初歩的なところから解説しているものが中々見つからない中、先生のblogは本当に重宝しております、ありがとうございます。

    ところで、shell scriptのpdfについて1つ質問があります。
    ” “(ダブルクオート)で*(ワイルドカード)が囲まれた場合、展開されないと4.7に書いてあるのですが、5.7では、「v=”im*.nii.gz” echo $v」とすると、ワイルドカードが展開された形で表示されます。これは、どのように解釈すればよろしいでしょうか?おそらくかなり初歩的な質問かと思われますが、ご教示いただけると幸いです。

    • ty様

      ご質問ありがとうございます。

      short answerとしては、(ワイルドカードだけなので)

      変数v は im*.nii.gz となるが、

      echo $vとした時点で、echo im*.nii.gzと指定したことと同じことになり、
      シェルにてワイルドカードが展開されるため、結果的にワイルドカードが展開される

      ということになります。

      Long answerとしては、以下をターミナルで試してみてください。

      まず、何もないディレクトリを準備します。たとえば、ホームディレクトリの下にtmpというディレクトリを作成し、そのディレクトリに移動します。

      $ mkdir tmp
      $ cd tmp

      次に、v=”im*.nii.gz”とタイプし、さらにecho $vとタイプしてください。

      $ v="im*.nii.gz"
      $ echo $v

      そうすると、

      im*.nii.gz

      と表示されるかと思います。

      次に、そのディレクトリの中にダミーでim1.nii.gz と im2.nii.gz というファイルを作成してみます。
      Linuxではtouchというコマンドを作ると、ファイルサイズ0のファイルが作成できます。

      $ touch im1.nii.gz im2.nii.gz

      このうえで先程と同じecho $vをしてみましょう。そうすると、違った結果となります。

      $ echo $v
      im1.nii.gz im2.nii.gz

      今、$vはim*.nii.gzです。ここにはダブルクオーテーションは入っていないことに注意が必要です。

      このため、echo $vは、

      echo im*.nii.gz

      と同じ意味を持ちます。従って、このワイルドカードはシェルに「これはワイルドカードだ」と理解されて、展開されることになるのです。

      では、次に以下をタイプしてください。

      $ echo "$v"

      そうすると、 im*.nii.gz と表示されませんか?

      今の場合は、

      $ echo "im*.nii.gz"

      と同じ意味になります。

      このとき、*はダブルクオーテーションで囲まれているため、シェルは、「これはワイルドカードではなく、ただの文字としての*だ」と理解するわけです。従って、展開されません。

      なお、ディレクトリの中にあてはまるファイルがない時も、ワイルドカードは展開されません。なので、最初に試していただいた、ファイルが何もない場合の、echo im*.nii.gzはあてはまるファイルがないのでダブルクオーテーションがなくても展開されずに文字列として出力されるわけです。

      少しまどろっこしい説明になってしまいましたが、こんな感じでいかがでしょうか?

      まとめると、以下のようになります。

      シングルクオーテーション:全ての文字列をそのまま出力。変数もワイルドカードも一切展開されない。
      ダブルクオーテーション:変数は展開するが、ワイルドカードは展開されない。ただ、変数の中にワイルドカードが入っている場合は、変数をダブルクオーテーションでくくらなければ、変数自体は展開されるために、ワイルドカードはシェルによって展開されてしまう。

      今の例で説明するならば、tmpディレクトリにim1.nii.gz, im2.nii.gzが入っているならば、

      v=’im*.nii.gz’
      v=”im*.nii.gz”

      は同じ意味になります。ワイルドカードはダブルクオーテーションでは展開されないために、シングルクオーテーションでくくっても、ダブルクオーテーションでくくっても同じなわけです。
      しかし、echo $vとするときに$vをどのようにくくるかの結果はそれぞれ異なります。

      $ echo $v
      これはecho im*.nii.gzと同じ意味ですので、im1.nii.gz, im2.nii.gzが表示されます。

      $ echo '$v'
      この場合、シングルクオーテーションの中身は全く展開されませんので、$vが表示されます。

      $ echo "$v"
      この場合、ダブルクオーテーションの中がまず展開されます。つまり、echo "im*.nii.gz"と同じ意味になります。
      ワイルドカードはダブルクオーテーションでは展開されませんので、
      im*.nii.gzが出力されます。

      • お忙しい中、私の理解度を考慮していただき、非常に丁寧なご説明ありがとうございました。
        先生の言われた通りに手を動かしていきますと、shell scriptを先生の翻訳で勉強し始めたばかりの私でもよく理解することができました。
        本当に感謝、感謝です。

        • ご丁寧にありがとうございます。
          理解の助けになったようでよかったです。
          シェルスクリプトは慣れてくると、作業を大幅に効率化できます。
          私もまだ学習中ですが、このFSLのシェルスクリプトのドキュメントは非常によくできているので、
          効率良く学ぶことができると思います。
          また何か疑問がありましたら、気軽にお聞きしていただけたらと思います。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください