ちょこっとプログラミング
仕事(や趣味)をしていると、しばしば、ちょこっとした短いプログラムを書かなくてはならなくなる。 ほとんどが「使い捨て」だけれども、何かの折に役に立つかもしれないと思ったものを、ここにまとめておくことにしました。
日本語のファイル名(ディレクトリ名)をローマ字に変更するRubyスクリプト
日本語のファイル名は何かと厄介なことが多いので、KAKASI を使い、まとめてローマ字に変換するRubyのスクリプトです。再帰を使って「深い」ところから順に名前を変えています。
日本語の曲名表示に対応していないような安いカーステレオで、日本語ファイル名のMP3を再生したい場合などに使えると思います。
convert-file-name.rb
#!/usr/bin/ruby
# coding: utf-8
require 'kakasi'
require 'nkf'
def search_and_rename(path)
Dir::foreach(path) { |file|
next if file =~ /^\./
if path =~ /\/$/ then
file = path + file
else
file = path + "/" + file
end
if File::ftype(file) == "directory" then
search_and_rename(file)
end
rename_to_ascii(file)
}
end
def rename_to_ascii(file)
path,name1 = File::split(file)
eucname = NKF.nkf('-We',name1)
begin
name2 = Kakasi.kakasi('-Ja -Ha -Ka -Ea -U', eucname)
rescue Encoding::UndefinedConversionError
name2 = name1
end
if name1 != name2 then
File.rename(file,path+'/'+name2)
end
printf("%s/%s -> %s\n",path, name1,name2)
end
filelist = Array.new
if ARGV.length == 0 then
filelist.push(".")
else
filelist.concat(ARGV)
end
filelist.each{|path|
search_and_rename(path)
}
GPX形式のファイルを数値の並びに変換するRubyスクリプト
GPSロガーの出力をgnuplotでプロットしたり他のプログラムで処理したりする際に書いたもの。時、分、秒、UNIX時間、経度、緯度の順にファイルに出力。
gpx2txt.rb
#!/usr/bin/ruby
# coding: utf-8
require "rexml/document"
require "time"
require "parsedate"
gpxfile_name = ARGV[0]
txtfile_name = File.basename(gpxfile_name,".*") + ".txt"
print "converting ",gpxfile_name," to ",txtfile_name,"\n"
doc = nil
File.open(gpxfile_name) {|xmlfile|
doc = REXML::Document.new(xmlfile)
}
txtfile= File.open(txtfile_name,"w")
trkseg = doc.elements["/gpx/trk/trkseg"]
trkseg.elements.each("trkpt"){|trkpt|
longtitude = trkpt.attributes.get_attribute("lon")
latitude = trkpt.attributes.get_attribute("lat")
time = trkpt.elements["time"].text
year,month,day,hour,min,sec,zone,dow = ParseDate.parsedate(time)
unixtime = Time.parse(time).to_i
txtfile.puts "#{hour} #{min} #{sec} #{unixtime} #{longtitude} #{latitude}"
}
UTF-8データのコードポイントをダンプするCプログラム
標準入力から読み込んで、16進数で標準出力に書き出すだけのプログラムです。
dump-utf8.c
#include <stdio.h>
#include <stdlib.h>
#define CHECK_BIT_PATTERN(x,y) (((x)&(y))==(y))
int GET_CHAR_FROM_FILE(FILE *fp)
{
int c0,c1,c2,c3 ;
c0 = fgetc(fp) ;
if (c0 == EOF) return EOF ;
if (CHECK_BIT_PATTERN(c0,0xf0)) {
c1 = fgetc(fp) ; if (c1 == EOF) return EOF ;
c2 = fgetc(fp) ; if (c2 == EOF) return EOF ;
c3 = fgetc(fp) ; if (c3 == EOF) return EOF ;
return ((c0 & 0x07)<<18) + ((c1 & 0x3f)<<12) + ((c2 & 0x3f)<<6) + (c3 & 0x3f) ;
} else if (CHECK_BIT_PATTERN(c0,0xe0)) {
c1 = fgetc(fp) ; if (c1 == EOF) return EOF ;
c2 = fgetc(fp) ; if (c2 == EOF) return EOF ;
return ((c0 & 0x0f)<<12) + ((c1 & 0x3f)<<6) + (c2 & 0x3f) ;
} else if (CHECK_BIT_PATTERN(c0,0xc0)) {
c1 = fgetc(fp) ; if (c1 == EOF) return EOF ;
return ((c0 & 0x1f)<<6) + (c1 & 0x3f) ;
} else {
return c0 ;
}
}
main()
{
int c ;
while ((c = GET_CHAR_FROM_FILE(stdin)) != EOF) {
printf("0x%04x\n",c) ;
}
}