未知の拡張子のファイルの basename をシェルで変更する



文字コードの変換前後のファイルを両方残しておきたい。拡張子は同じで basename を変更して保存する方法。

文字コード変換の必要な場面

iPhoneアプリなどから吐き出されるCSVファイルのログの文字コードは大体 UTF-8 だ。これを、エクセルなどで解析する場合、日本語環境では UTF-8 から Shift_JIS への変換が必要になる。

ファイルを上書きしてしまって良い場合は以下のようなシェルスクリプトを作っておくと1コマンドで変換ができる。

ファイルを上書きしていい場合の UTF-8 -> Shift_JIS 変換スクリプト

#!/bin/sh
#usage: nkf4csv.sh FILENAME

nkf -W -s $1 > $1.tmp && mv $1.tmp $1

実行例

nkf4csv.sh logfile.csv

文字コード変換したCSVを別のファイル名で保存したい場合

以下のように、文字コード変換した後のファイルを毎回対応づけて保存しておきたい場合がある。このような場合は、ファイルの basename 部分に文字を追加しておきたい。また、Windows を生活マシンにしているので、拡張子も保存したい。例えば、.csv だけでなく .log や .txt にも汎用的に使えると便利。

文字コード変換後の保存ファイル名(希望)

log201308.csv → log201308-sjis.csv
20130808.log → 20130808-sjis.log
console.txt → console-sjis.txt

拡張子を変更せずに basename を変更して保存する変換スクリプト

ということで、シェルスクリプトを作成。
シェルの basename コマンドは拡張子が分からないと basename を取り出せないが、シェルの正規表現を使って拡張子を抽出しておくと、未知の拡張子に対応できる。

#!/bin/sh
#convert charset from utf8 to sjis
#usage uni2sjis.sh FILENAME

file=$1
ext=${file##*.}

nkf -W -s $file > `basename $file .$ext`-sjis.$ext

シェルの正規表現

シェルの正規表現は本を読んでも分かりにくかったのだが、このページの説明を読んですっきり。Thanks! m(..)m

なんちゃって鶯教 シェル制御構造と正規表現の基礎・UNIXテクニック集
http://uguisu.skr.jp/Windows/unix_tips0.html

変数展開    説明
${パラメータ#パターン}    パラメータ前方から、パターンに最短一致した部分を除く
${パラメータ##パターン}    パラメータ前方から、パターンに最長一致した部分を除く
${パラメータ%パターン}    パラメータ後方から、パターンに最短一致した部分を除く
${パラメータ%%パターン}    パラメータ後方から、パターンに最長一致した部分を除く