以下に改良版 Ruby スクリプトを示します。

001:     #! /usr/bin/env ruby
002:     #----------------------------------------------------
003:     # achive photos in the removal media into HD
004:     # by T.Shido
005:     # September 23, 2006
006:     #
007:     # modified version according to suggestions by blackbox. thanks!
008:     #----------------------------------------------------
009:     
010:     require "FileUtils"
011:     
012:     #global parameters
013:     Doc_dir = "D:/doc"
014:     Media = "F:"
015:     Viewer = "D:/WBIN/linar160/linar.exe"
016:     PEXP =  /\.(jpe?g|bmp|tiff?)$/i
017:     $photo_hash = Hash.new
018:     
019:     # to accelerate copying from media to HD by incleasing the block size
020:     module FileUtils
021:       module StreamUtils_
022:         def fu_default_blksize
023:           64 * 1024
024:         end
025:       end
026:     end
027:     
028:     # functions
029:     
030:     # getting the number of photoNN in the dir of month
031:     def photo_dir_max(dir)
032:         Dir.chdir(dir)
033:         d = Dir.glob("photo[0-9][0-9]").select{|f| File.directory?(f)}
034:         d ? d.last.slice(5..6).to_i : 0 
035:     end
036:     
037:     def search_media(dir)
038:         files=[]
039:         Dir.chdir(dir)
040:         Dir.foreach(dir){|f|
041:             if f =~ PEXP then
042:                 files << f 
043:             elsif File.directory?(f) and (not [".", ".."].include?(f))
044:                 search_media(File.join(dir,f))
045:             end
046:         }
047:         $photo_hash[dir] = files unless files.empty?
048:     end
049:     
050:     def move_photos ()
051:         mon_dir = File.join(Doc_dir, Time.new.strftime("%y-%m"))
052:         
053:         if File.directory?(mon_dir) then
054:             p_d_num = photo_dir_max(mon_dir)
055:         else
056:             FileUtils.mkdir(mon_dir)
057:             p_d_num = 0
058:         end
059:         
060:         count = 0; p_dir0 = nil                                            
061:         total = 0; $photo_hash.each_value{|v| total += v.size}
062:         
063:         if total == 0 then
064:             puts "NO photo files in the media."
065:             STDIN.readline
066:             exit(0)
067:         end
068:         
069:         $photo_hash.each{|d, files| 
070:             p_d_num += 1
071:             p_dir = File.join(mon_dir, sprintf("photo%02d", p_d_num))
072:             p_dir0 = p_dir if p_dir0.nil?                                 
073:             FileUtils.mkdir(p_dir)
074:             files.each{|f|
075:                 f1, f2 = File.join(d, f), File.join(p_dir, f)
076:                 FileUtils.cp(f1, f2)
077:                 FileUtils.cmp(f1, f2) ?  File.delete(f1) : printf("Copy failed: %s => %s\n", f1, f2)
078:                 count += 1
079:                 printf("%d/%d\r", count, total) 
080:             }
081:         }
082:         p_dir0
083:     end
084:     
085:     # main
086:     search_media(Media)
087:     exec(Viewer, move_photos())

説明

説明
20—26 ブロックサイズを大きくすることによってコピー速度を速くします。
これによってだいぶ速度が改善します。
31—35 glob は文字列の昇順にソートするので photo00 — photo99 の順に並びます。
photoNN の数はそんなに多くないので、glob して select しても大してメモリーは消費しません。
こう書いた方が簡潔です。
[戻る]