[ヅ] まともじゃない日時文字列をRubyでパースする (2014-07-29) で書いたコードを利用して、ファイルをリネームする Ruby スクリプトを書いた。
#!/usr/bin/env ruby
require 'date' # using DateTime
# 年表現を正規化
def normalize_year(y)
# 年が2桁以下の場合、2000年以降とみなす
# return (y < 100) ? (2000 + y) : y
# 年が2桁以下の場合、平成年とみなす
# return (y < 100) ? (1988 + y) : y
# 何もしない
return y
end
# フォーマットがわからない文字列を日時オブジェクトへ変換する
def parse_datetime(s)
# 数字以外の文字で分割する
strlist = s.split(/\D/)
# 空文字列を削除
strlist.reject!{|i|i.empty?}
# 整数に変換
intlist = strlist.map(&:to_i)
# パターンに応じて DateTime オブジェクトを生成する
if intlist.length == 6 then
# 6個のときは[年,月,日,時,分,秒]
intlist[0] = normalize_year(intlist[0])
return DateTime.new(*intlist)
elsif intlist.length == 3 then
# 3個のときは[年,月,日]
intlist[0] = normalize_year(intlist[0])
return DateTime.new(*intlist)
elsif strlist.length == 2 then
# 2個のときは[年月日,時分秒]
strlist = [
strlist[0][ 0..-5],
strlist[0][-4..-3],
strlist[0][-2..-1],
strlist[1][ 0..-5],
strlist[1][-4..-3],
strlist[1][-2..-1],
]
intlist = strlist.map(&:to_i)
intlist[0] = normalize_year(intlist[0])
return DateTime.new(*intlist)
elsif strlist.length == 1 then
# 1個のときは[年月日時分秒]
strlist = [
strlist[0][ 0..-11],
strlist[0][-10..-9],
strlist[0][ -8..-7],
strlist[0][ -6..-5],
strlist[0][ -4..-3],
strlist[0][ -2..-1],
]
intlist = strlist.map(&:to_i)
intlist[0] = normalize_year(intlist[0])
return DateTime.new(*intlist)
else
# あきらめて標準ライブラリにまかせる
return DateTime.parse(s)
end
end
def get_new_file_path(filepath, datetime)
datetimestr = datetime.strftime('%Y%m%d_%H%M%S')
ext = File.extname(filepath)
dir, file = File::split(filepath)
return "#{dir}/#{datetimestr}#{ext}"
end
def rename_by_datetime(filepath)
begin
ext = File.extname(filepath)
base = File::basename(filepath, ext)
datetime = parse_datetime(base)
if datetime != nil
newfilepath = get_new_file_path(filepath, datetime)
# リネーム先にファイルが存在する場合はリネームしない
if !File.exist?(newfilepath)
File.rename(filepath, newfilepath)
return newfilepath
else
return nil
end
else
return nil
end
rescue
return nil
end
end
ARGV.each{|filepath|
newfilepath = rename_by_datetime(filepath)
if newfilepath != nil
# success
puts "rename: #{filepath} -> #{newfilepath}"
else
# failure or untouched
puts "keep: #{filepath}"
end
}
if ARGV.size < 1
puts "Usage: ruby #{File.basename(__FILE__)} <files>"
end
tags: ruby
Posted by NI-Lab. (@nilab)