#!/usr/bin/env ruby #http://pastebin.com/KSS0zU2F unless ARGV.count == 1 abort 'Merges sequentially-named files.' end outfile = ARGV.first.sub(/.?\d+\z/, '') if File.size? outfile abort 'The outfile already exists.' end pattern = ARGV.first.sub(/\d+\z/, '') pattern.gsub!(/[\[\]\*\{\}]/, "\\\\\\0") if digits = ARGV.first[ /\d+\z/ ] pattern << '[0-9]' * digits.length else pattern << '.[0-9]*' end files = Dir.glob(pattern).sort if files.count < 2 abort 'There needs to be at least 2 files.' end if files.first[ /\d+\z/ ].to_i != 1 abort 'The first file in the series is missing.' end file_count = files.last[ /\d+\z/ ].to_i unless files.count == file_count abort '%s of %s files are missing.' % [ file_count-files.count, file_count ] end unless size = File.size?(files.first) abort '"%s" is empty.' % files.first end if File.size?(files.first) == File.size?(files.last) abort 'One or more files seem to be missing.' end files[0..-2].each do |path| size == File.size?(path) and next abort '"%s" has an incorrect size.' % file end File.open outfile, 'w' do |outstream| files.each do |path| puts 'Merging "%s"' % path File.open(path) do |instream| IO.copy_stream(instream, outstream) end end outstream.fsync end files.each(&File.method(:unlink))