スライドショースライドショー

【完全網羅】Rubyのディレクトリ・ファイル操作まとめ(dir, file)

こんにちは! フリーエンジニアの長瀬です。

みなさんはディレクトリ(フォルダ)やファイルをプログラムで管理していますか?

ディレクトリやファイルの操作を極めれば、繰り返し大量のファイルを作成できたりととても便利です。

この記事では、ディレクトリやファイル操作について

・ ディレクトリの作成
・ 現在のディレクトリの取得
・ ディレクトリの削除
・ ディレクトリのコピー
・ ディレクトリの移動
・ ディレクトリの名前変更
・ ディレクトリの名前を取り出す
・ カレントディレクトリの移動
・ ディレクトリが存在するか確認
・ ディレクトリのファイル一覧を取得

という基本的な内容から、

・ ホームディレクトリを取得
・ ディレクトリかどうか判断する
・ ファイル名をディレクトリの部分だけにする
・ ディレクトリ内のファイル全てに処理をする
・ 任意の文字列を含むファイルを取得
・ findでファイルを取得する
・ ファイルを再帰的に作成する

といった応用的な内容についても解説していきます。

ディレクトリ操作の基本

ディレクトリの作成

Dir::mkdir("sample")

ファイル名の部分は現在のRubyファイルから見た相対パスを入力しましょう。

相対パスとは、Rubyファイルから見たそのディレクトリの位置を指します。
同じ階層であれば「./」、一つ上のディレクトリであれば「../」とします。
同じ階層にファイルを作りたければ、特に気にせずにファイル名を入力してください。

またディレクトリを作成する際は現在のディレクトリを確認しましょう。

現在のディレクトリの取得

「pwd」は「Print Working Directory」のことで現在作業をしているディレクトリを取得します。

基本的なコマンドで、よく使うので2秒で入力できるようにしておきましょう。

Dir::pwd

ディレクトリの削除

ディレクトリを削除するには3つのコマンドがあります。

Dir::rmdir("sample")
Dir::delete("sample")
Dir::unlink("sample")

これで削除できるのですが、中身が空である時のみ削除が実行されます。
中身が空でなければ削除できないので気を付けましょう。

ディレクトリのコピー

ディレクトリのコピーは「FileUtils」を用います。

require 'fileutils'
FileUtils.cp_r("sample","sample2")

サンプルのソースコードは次の通りですが、このサンプルはあらかじめ「tmp」というフォルダに「a.txt」を入れてあります。

require "fileutils"

FileUtils.cp_r("tmp/","tmp2/")

「tmp2」というディレクトリが無くてもそれを生成して中身をコピーしてくれます。
また、「tmp2」というディレクトリをあらかじめ作成しておくと「tmp2」内部に「tmp」を丸ごとコピーしてくれます。

FileUtilesの使い方はこちらで詳しく説明してありますので、一読することをおすすめします。

ディレクトリの移動

require 'fileutils'
FileUtils.mv("sample","sample2")

このプログラムを実行すると、ディレクトリsampleがsample2に変更されます。

ディレクトリの名前変更

File.rename("sample","sample2")

これでsample→sample2に変わります。

ディレクトリの名前を取り出す

ディレクトリの名前を取得します。

File.dirname("sample")

指定したファイルの存在するカレントディレクトリを取得することができます。
使い方は以下の通りですが、事前に「a.txt」というフォルダを作成しておきましょう。

puts File.dirname("a.txt")

実行結果は次のようになります。

.

「.」はカレントディレクトリを表します。

カレントディレクトリとは現在のディレクトリのことです。

「.」は現在のディレクトリを表現したいときによく使用します。

カレントディレクトリの移動

今いるディレクトリを移動するときに使います。

Dir::chdir("sample")

使い方は次の通りです。
1つ上のディレクトリに移動して、現在地を表示しています。

Dir::chdir("..")
puts Dir::pwd

ディレクトリが存在するか確認

Dir::exist?("sample")

True か False で表示されます。

ディレクトリのファイル一覧を取得

Dir::entries("sample")

以下のように記述するとカレントディレクトリに存在するファイルを取得します。

Dir::entries(".")

ディレクトリ操作の応用

ホームディレクトリを取得

ホームディレクトリに相当するディレクトリを取得できます。

Dir::home

ディレクトリかどうか判断する

File::ftype("sample")

ディレクトリである場合にtrueを返します。

反対にディレクトリでない場合にはfalseを返します。

ファイル名をディレクトリの部分だけにする

p File::dirname("/usr/local/bin/ruby/sample")
p File::dirname("/etc/sample/main") 

/usr/local/bin/ruby
/etc/sample

がそれぞれ取り出されます。

ディレクトリ内のファイル全てに処理をする

Dir::foreach("sample"){
  処理
}

それか

Dir::open("sample"){|d|
 d.each{
 処理
}

です。

以下にサンプルを書きます。
あらかじめ、「a.txt」「b.txt」「c.txt」を作成しました。

Dir::foreach("."){|f|
  puts f
}
Dir::open('.') {|d|
  d.each {|f|
    puts f
  }
}

「a.txt」「b.txt」「c.txt」は出力されましたでしょうか。
このように1つ1つに処理を適用することもできます。

任意の文字列を含むファイルを取得

ワイルドカードと呼ばれるパターン認識を使えば、あるパターンに合致したファイルだけを取得することができます。

p Dir.glob("*")   

以下にサンプルを書きます。

例えば、ディレクトリ下にfire.rb、water.rb、thunder.rbがあるします。

この中からfire.rbだけを取得したい場合は

p Dir.glob("f*")

と書けます。

*は"なんでも"表現しているので、例えばこの場合fire.rb以外にfjeoiwjrjei.rbやf458773747lfj.txtがあったとしても取得されます。

また、複数の条件を指定する場合は

p Dir.glob(["f*","t*"])

と書けて、この場合fire.rbとthunder.rbが取得されます。

findでファイルを取得する

findメソッドを使っても、ファイルを取得することができます。

先ほど紹介したglobとの違いはファイルの読み込み方法にあります。

globは始めにすべてファイルを取得してから処理を実行しますが、findメソッドでは1つ1つファイルに処理を加えていきます。

findの優位な点はglobに比べて処理を開始する時間が若干速いということです。

というのも、globは始めにすべてのファイルを読み込む分だけ遅くなるからです。

findで現在のディレクトリのファイル一覧を取得するには以下のようにします。

require 'find'
Find.find('.') do |file|
  next if file == '.'
  puts file
end

「.」は現在のディレクトリを表し、出力結果にも「.」が含まれます。

なので、nextを使って、'.'のときは出力しないように工夫しています。

nextを使った後置ifについてはこちらで体系的にまとめられているのでよくわからないという方は一読することをおすすめします

ファイルを再帰的に作成する

これまで、学習した知識を組みわせて再帰的にファイルを作成してみましょう。

以下のコードは現在のディレクトリにhoge0、hoge1、hoge2という新たなディレクトリを作成して、それぞれに0.txt、1.txt、2.txtというファイルを再帰的に作成します。

3.times do |i|
directory = "hoge#{i}"
Dir::mkdir(directory)
Dir::chdir(directory)
3.times do |j|
f = File.new("#{j}.txt",'w')
f.close
end
Dir::chdir('..')
end

実行すると計9つのファイルが作成されているのを確認できます。

また、上記のコードでは本記事で学習したことのほかに、Fileクラスを使って動的にファイルを作成していますが、Fileクラスについて理解が浅いと思う方はこちらの記事を一読することをおすすめします。

【Ruby入門】ファイルの読み込みと書き込みまとめ(File open)
更新日 : 2019年8月2日

まとめ

いかがだったでしょうか。
ディレクトリの操作はDir, File, FileUtilsの三つのクラスで行うという事が分かっていただけたでしょうか。
Railsなどのgemの内部コードでもこれらのディレクトリ操作はよく出てくるため、覚えておいて損はないでしょう。
サーバーなどでもRubyを用いてディレクトリ操作ができるとできることも広がります。
ぜひ、習得してみましょう!


【Ruby入門】日付・時刻の扱い方(Date、DateTime、Time)
更新日 : 2019年6月26日

【5分で理解】Rubyでスクレイピングの基礎を解説!
更新日 : 2018年6月11日

LINEで送る
Pocket

無料でSEからWebエンジニアへ転職しませんか?



侍エンジニア塾では、完全未経験の方から現在SEだけどプログラミングはやっていないという経験者まで、幅広い方々の人生を好転させるプログラミング指導を行ってきました。SEの方とお話していくなかで、

  • システムエンジニアという職業だけどコードが書けない
  • 事務作業が多くスキルがないため将来が不安
  • スクールに通うと完全未経験者と同じスタートになるからレベルが合わない
という、すでに知識があるSEならではのお悩みがあることに気づきました。そんな方におすすめなのが、弊社の「転職コース 」です。

弊社では、マンツーマンでレッスンを行いますので、現在お持ちの知識レベルからカリキュラムを作成いたします。さらにこちらの転職コースは無料で受講を始められて転職成功でそのまま卒業できるというとてもお得なコースとなっています。

既に知識のあるSEといっても転職は年齢が若いほど受かりやすいため、まずは無料体験レッスンで今の現状や理想の働き方について一緒に考えていきましょう。

まずは無料体験レッスンを予約する

書いた人

長瀬来

長瀬来

Unityを使ったiOSアプリのリリース、フリマサイト運営の経験があります。

経験した言語はC、C#、Javascript、R、Python、Ruby、PHPなど

言語が好きで、英語や中国、ドイツ語を勉強しました。
将来的には海外で生活したいです。

現在はRuby on Rails5やCocos2dxの勉強を主にしています。

ライターとしては
できるだけ初心者にわかりやすい文章になるように心がけています。

趣味は語学、読書です。

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説