前記事「【Ruby入門】ファイルの移動、コピー、削除」では、ファイルの操作を解説しました。
今度はフォルダの操作を解説します。
単純にフォルダの操作だけでは面白くないので、前記事と本記事を合わせて、現場でよく使う技術を解説します。
今までどちらかというと技術ごとのピンポイントの解説となりましたが、それらを連続して一連の流れを作ってみます。
本解説を通じて、点の理解がつながって線の理解になることを願ってやみません。
※本解説は、UnixやMacの表記にならって進めます。
※Windowsをお使いの方は「/」を「¥」に置き換えてください。
フォルダ(ディレクトリ)の簡単な解説
超簡単に、前提となる知識を整理しておきましょう。
フォルダとは、ファイルやフォルダを格納するものです。
フォルダの中には、ファイルやフォルダが混在できるのはご存知のとおりです。
前記事では「フォルダ」という用語で解説しましたが、これではどうしても理解が頭打ちになることがあります。
「フォルダ」といってしまうと画面上のアイコンや、文具でいう実物のフォルダからくる入れ物のイメージが理解をさまたげるのです。
フォルダはファイルシステム的にいうと正しくはディレクトリで、ディレクトリを理解するためには階層構造のイメージを持たないといけません。
なぜなら、上の階層、下の階層を行ったり来たり、といった操作を頻繁に行うからです。
よってこれ以降、ディレクトリという用語で解説を進めます。
カレントディレクトリという考え方
「では、ディレクトリの中身を表示してください」
いきなりこういわれれば、困りますよね。
それもそのはず、ディレクトリはたくさんあるので、どこの中身かわかりません。
では、今どこのフォルダにフォーカスが当たっているのか(つまり操作の拠点は今どこか?、もっと簡単にいうと今どこにいるのか)を表現する言葉として、カレントディレクトリ(current directory)を覚えておきましょう。
上図で例えれば、カレントディレクトリがchild1なら、ディレクトリの中身はといわれればsample3.txtとなり、parentがカレントディレクトリなら中身はchild1,child2,sample1.txt,sample2.txtとなります。
parentディレクトリを一番頂点とすれば、parentをルートディレクトリと呼びます。
相対パスと絶対パス
parentからみたsample4.txtを表現するとこうなります。
/parent/child2/sample4.txt
このように、ルートディレクトリからみて、ディレクトリを「/」で区切って表現したものを絶対パスといいます。
一方、sample3.txtからみたsample4.txtはこうなります。
.././child2/sample4.txt
「..」は1つ上の階層、「.」はその直下という意味です。つまりsample3.txtがいる階層から、
- ひとつ上がる(parent)
- parent直下のchild2
- その中のsample4.txt
という意味です。つまりどこか特定のディレクトリやファイルから、目的の場所までの通り道の表現方法を相対パスといいます。
絶対、相対にかかわらず、目的とするファイルやディレクトリまでの表現をパスといいます。
ディレクトリの作成
いよいよ、Rubyによるディレクトリの操作です。
まずは作成から。
作成はDirクラスのmkdirメソッドを使います。
Dir.mkdir("back")
たったこれだけです。
パス指定をしていないので、カレントディレクトリの直下にbackフォルダができましたが、もちろんパス指定は可能です。
ディレクトリの削除
ディレクトリの削除は
Dir.rmdir
を使います。
カレントディレクトリ直下のbackフォルダを削除しましょう。
Dir.rmdir("back")
ただし、backの中身が空である必要があります。
中に何かファイルがあるとこういうエラーが返ります。
`rmdir': Directory not empty
これを防ぐために、前記事「【Ruby入門】ファイルの移動、コピー、削除」で出ていたfileutilsを使います。
require 'fileutils' FileUtils.rm_r("back")
rm_rでディレクトリを指定すると、その中身はおろかディレクトリごと削除してくれます。
挑戦!ログファイルの移動
ファイルの一連の流れを組んでみる
今まで学んだことを活かして、以下のようなシーンを想定しましょう。
特定のフォルダに、日付をファイル名としたログファイル(例えば20171130.log)が多数あるとします。
月が変わって2017年12月になったので、前月の年月(201711)でフォルダ名を作り、そこへ前月分を移します。
先頭1〜6文字が201711のものが前月のログファイルとします。
ただし、移動するときは前の月(つまり2017年11月分)と当月分(2017年12月分)が混在しているとします。
ちょっと難しいですが、やってみましょう。
=begin 前提条件は以下のとおり。 1.毎日動く 2.絶対過去日付で動かない!! 3.拡張子はlogのみ対象とする。 4.当月初日は、前月当月が混在。 =end require 'date' require "fileutils" d = Date.today # 毎月1日でなければ、強制的に処理終了 if d.day != 1 return end # 前月の年月を取得 prev_month = d.prev_month.strftime("%Y%m") # 前月の年月を名称としたフォルダを作成 Dir.mkdir(prev_month) # 拡張子がlogのファイルで、かつ前月分は移動 Dir.glob('*.log').each do |filename| if filename[0,6] == prev_month FileUtils.mv(filename, prev_month + "/" + filename) end end
これで、カレントディレクトリ内の前月のログだけを前月のディレクトリに移すことができました。
解説
1行だけのコメントなら、行頭に#を書きます。複数行を一気にコメントにする場合は、=beginと=endで囲います。
d.prev_month.strftimeは、d.prev_monthで前月取得、.strftimeでそれをYYYYmm形式へ変換するという作業を一気に書いています。
あとは、今までの解説で十分理解できるはずです。
まとめ
本記事では、今までの復習+ログファイル移動というテーマを実践しました。
今までの知識だけでも結構なことができること、お気づきでしょうか?
さらにいろんな手を加えて、遊んで、理解してみてくださいね!