13
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rubyのスクリプトでファイル名一括置換

Last updated at Posted at 2016-01-28

2016.1.29
scivolaさまにご指摘を受け、一部コードを修正しました。ありがとうございます。

はじめに

初心者向けです。

Rubyに少しは触ってみたい…と漠然と思っていたのですが、
ファイル名を一括でいじりたいなーという機会があり、勉強がてらスクリプトを書いてみました。
(普通にシェルでやれとかリネームツール使えとかいう話ですが…)

指定拡張子のファイルを連番にしたい

同じ種類のファイルを連番にしたいなーというとき用。

rename_target_extension.rb
# 指定拡張子のファイル名を連番にしたい

require 'fileutils'

target = ARGV[0]
prefix = ARGV[1]

if target.nil?
   print "対象とする拡張子を入力してください\n"
   exit
end

Dir.glob("*.#{target}").each_with_index do |filename, index|
  newname = filename.gsub(/.+(?=\.[^.]+$)/) { sprintf("%s%03d", prefix, index) }
  print "#{filename} -> #{newname}\n"
  FileUtils.mv(filename, newname)
end

実行してみる

リネームしたいフォルダで実行するとこんな感じになります。

$ ruby rename_target_extension.rb png hoge
aaa.png -> hoge000.png
bbb.png -> hoge001.png

ファイル名内の指定文字列を置換したい

上で連番にしたようなファイル郡があるときに、一括でファイル名を変更する用。

rename_target_string.rb
# ファイル名の一部をまとめて置換したい

require 'fileutils'

target = ARGV[0]
conv = ARGV[1]

if target.nil?
  print "対象文字列が空です\n"
  exit
end

Dir.glob("*") do |filename|
  newname = filename.gsub(/#{target}/, "#{conv}")
  if newname != filename
     print "#{filename} -> #{newname}\n"
     FileUtils.mv(filename, newname)
  end
end

実行してみる

リネームしたいフォルダで実行するとこんな感じになります。

$ ruby ../../rb_script/rename_target.rb ho sa
hoge000.png -> sage000.png
hoge001.png -> sage001.png

できました\('ω')/

詳解メモ

ここからは自分用のメモみたいなものです。

ライブラリのロード

require 'fileutils'

fileutilsをロードすることで、ファイル操作を行えるようになります。

コマンドライン引数の取得

target = ARGV[0]
prefix = ARGV[1]

コマンド実行時の引数はARGV[]で取得します。
さらに複数ある場合はARGV[2], ARGV[3]..と入ってきます。
因みに、ruby実行時のファイル名自体を取得したい場合、$0で取得できます。
(上記実行例であれば$0で "rename_target_extension.rb" が取得できる)

変数の展開

文字列中に式の結果や変数の中身を使いたい場合は、#{}でくくります。

Dir.glob("*.#{target}")

フォルダ内のファイル取得

Dir.glob("*.#{target}") do |filename|

Dir.glob()の引数にマッチするファイルを、カレントディレクトリから取得します。
例えばDir.glob("*")などとすれば全てのファイルが対象になります。

Dir.globだけですと配列を返しますが、
例のように Dir.glob(..) do |filename| .. end としたり、
Dir.glob { |filename| .. } とすることで、取得した各ファイル名に対する処理を行うことができます。

文字列の置換

filename.gsub(/#{target}/, "#{conv}")
filename.gsub(/.+(?=\.[^.]+$)/) { sprintf("%s%03d", ARGV[1], index) }

文字列に対し、gsubを使えば置換が行えます。
正規表現で置換対象を抜き出すこともできます。
複雑な式などはブロック形式(filename.gsub(..){ .. })の方が見やすくて良さそうですね。

拡張子以外の文字列の抽出

(/.+(?=\.[^.]+$)/)

拡張子を除く部分を抽出する正規表現です。
ざっくり説明すると、**.+で文字列全体を指定し、
そこから
(?=\.[^.]+$)**で拡張子部分を排除しています。

**\.[^.]+$**がカンマから始まってカンマ以外の文字が続いたのち文字列の最後尾に達する部分を示し、
**?=**がその否定を表しています。

(´-`)oO(正規表現ちゃんと勉強しないとなあ…)

13
13
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?