ファイルに特化したcat

30分プログラム、その163。ファイルに特化したcat。
最近、複数のJavascriptを結合するのにcatを使ってる。(id:mzp:20071013:js)

cat *.js > foo.js

ただ、これだと結合したやつから元のファイルを得ることができなくて、たまに困る。

そこで、結合時にファイル名を埋め込んでおいて、あとからばらせるようにしてみる。

使い方

結合は、普通のcatと同じ。ただし標準入力は無視してる。

$ fcat a.txt b.txt c.txt
// == a.txt == dont remove this line
a
a
...
// == b.txt == dont remove this line
b
b
...
// == c.txt == dont remove this line
c
c
...

で、これを分解できる。

# [a-c].txtをfoo.txtにまとめる
$ fcat ~/a.txt ~/b.txt ~/c.txt > foo.txt

# 分解する
$ fcat --split foo.txt

$ ls
a.txt b.txt c.txt

ソースコード

optparseじゃないコマンドラインパーサがあることを知ったので、試してみる。
どちらが便利とも言えないな。

#! /opt/local/bin/ruby -w
# -*- mode:ruby; coding:utf-8 -*-
#
# fcat - file cat
#
# Copyright(C) 2007 by mzp
# Author: MIZUNO Hiroki <hiroki1124@gmail.com> 
# http://mzp.sakura.ne.jp/
#
# Timestamp: 2007/10/24 21:33:12
#
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Ruby itself.
#
require 'getoptlong'
def cat(*paths)
  paths.each{|path|
    puts("// == #{File.basename path} == dont remove this line",
         File.read(path))
  }
end

def split(io)
  dest = nil
  io.each{|line|
    case line.chomp
    when %r!\A// == (.*?) ==!
      dest.close if dest
      dest = File.open($1,'w')
    else
      rasie 'must not happen' unless dest
      dest.print line
    end
  }
end


option = GetoptLong.new
option.set_options(['--cat'  ,'-c', GetoptLong::NO_ARGUMENT],
                   ['--split','-s','--dog',GetoptLong::NO_ARGUMENT])

type = '--cat'
option.each_option do|name,arg|
  type = name
end

case type
when '--cat'
  cat(*ARGV)
when '--split'
  io = if ARGV.empty? then STDIN else File.open(ARGV.first) end
  split io
end