ディレクトリ構造を保ったままフィルタ
ファイルをスクリプトで加工する、なんてことはよくあることなんだけど、最近、ディレクトリ以下のファイルに対して処理をして、別のディレクトリに出力したいってケースが多かったりする。
たとえば、
from/foo/00 from/foo/01 from/bar/00 from/bar/01
ていうファイル群を処理して、
to/foo/00 to/foo/01 to/bar/00 to/bar/01
に出力したい。
いまいちうまい方法が思いつかなかったから、適当に Ruby で汎用的なスクリプトを組んでみたんだけど、なんかいい方法ってないのかな。
ちなみにこう使う。
./dir_filter.rb -f from -t to -- grep -E -v '^\s*$/'
この場合、from ディレクトリ中のファイルの空白行が削除されて to に出力される。
#!/usr/bin/env ruby require 'pathname' require 'shell' require 'optparse' def main(from, to, debug, commands) files = [] from.find do |path| files << path if path.file? end if debug > 0 STDERR.puts "from_dir = #{from.to_s}" STDERR.puts "to_dir = #{to.to_s}" end files.sort.each do |file| dest = to + file.relative_path_from(from) dest.parent.mkpath if debug > 0 STDERR.puts "input = #{file.to_s}" STDERR.puts "output = #{dest.to_s}" end Shell.new.transact do system(*commands) < file.to_s > dest.to_s end end end if $0 == __FILE__ from = nil to = nil debug = 0 opt = OptionParser.new opt.on('-t', '--to TO', String) {|v| to = Pathname.new v} opt.on('-f', '--from FROM', String) {|v| from = Pathname.new v} opt.on('-d', '--debug') { debug += 1 } opt.parse!(ARGV) unless from and to and ARGV.length > 0 puts opt.help exit end main(from, to, debug, ARGV) end