2011/12/14

日付を2進数とか16進数に変換してみるshell script(date, bc)

最近「入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界」って本を読んでて、シェルスクリプト書いてみてます。

普段は何かやりたいことがあればGaucheで書いています。ですがシェルスクリプトで書いた方が手軽な場合も多々あります。やりたいことがあったときにシェルスクリプトで書くか、お気に入りの言語で書くか、この辺の判断はまだできません。シェルスクリプト書くのが結構楽しいので、もうちっと書きながら勉強してみます。

当初考えていたやりたいことを実現するにはシェルスクリプトで十分でした。が、機能を付け加えていくうちに「Gaucheでやればよかった・・・」という状況になりました。。なぜかというとコードが手続き的でわかりにくくて面倒になったからです。まだシェルスクリプトの作法がわからないこともありますが、文法的に手続き的なコードになりやすい印象を受けます(そりゃそうだろうと思いますが)。手続き的なコードが苦手なのであーあーあーあーあー状態。

で、本題。
date2binという名前を見ればわかるように、日付を2進数に変換してみようと思ったのがきっかけでした。そのうち16進数も、8進数も、CSVにも、といろいろやってるうちに面倒なことに。
$ date2bin -n3
--------------------
count          : 0
+%Y-%m-%d      : 2011-12-14
+%s            : 1323788400
+%Y%m%d -> bin : 1001100101101111101101110
+%m%d -> bin   : 10010111110
+%s -> bin     : 1001110111001110110100001110000
+%Y%m%d -> oct : 114557556
+%m%d -> oct   : 2276
+%s -> oct     : 11671664160
+%Y%m%d -> hex : 132DF6E
+%m%d -> hex   : 4BE
+%s -> hex     : 4EE76870
--------------------
count          : 1
+%Y-%m-%d      : 2011-12-15
+%s            : 1323874800
+%Y%m%d -> bin : 1001100101101111101101111
+%m%d -> bin   : 10010111111
+%s -> bin     : 1001110111010001011100111110000
+%Y%m%d -> oct : 114557557
+%m%d -> oct   : 2277
+%s -> oct     : 11672134760
+%Y%m%d -> hex : 132DF6F
+%m%d -> hex   : 4BF
+%s -> hex     : 4EE8B9F0
--------------------
count          : 2
+%Y-%m-%d      : 2011-12-16
+%s            : 1323961200
+%Y%m%d -> bin : 1001100101101111101110000
+%m%d -> bin   : 10011000000
+%s -> bin     : 1001110111010100000101101110000
+%Y%m%d -> oct : 114557560
+%m%d -> oct   : 2300
+%s -> oct     : 11672405560
+%Y%m%d -> hex : 132DF70
+%m%d -> hex   : 4C0
+%s -> hex     : 4EEA0B70
--------------------
$ date2bin -fn3
count,ymd,epoch,ymd_bin,md_bin,epoch_bin,ymd_oct,md_oct,epoch_oct,ymd_hex,md_hex,epoch_hex
0,2011-12-14,1323788400,1001100101101111101101110,10010111110,1001110111001110110100001110000,114557556,2276,11671664160,132DF6E,4BE,4EE76870
1,2011-12-15,1323874800,1001100101101111101101111,10010111111,1001110111010001011100111110000,114557557,2277,11672134760,132DF6F,4BF,4EE8B9F0
2,2011-12-16,1323961200,1001100101101111101110000,10011000000,1001110111010100000101101110000,114557560,2300,11672405560,132DF70,4C0,4EEA0B70
コードはこちら
#!/bin/sh
# date2bin
this_usage () {
echo 'Usage: date2bin [-ndf]'
echo ' n : number of days count as integer'
echo ' f : display flat line'
echo ' d : start date as integer (ex. $ date +%Y%m%d)'
echo ' h : display this usage'
exit 0
}
fmt_date (){
echo "obase=$1;"`date -d "$2" "$3"` | bc
}
VALUE_LIMIT=1
VALUE_START_DATE=`date +%Y%m%d`
FLG_FLAT="FALSE"
#
# parse options
#
while getopts hn:fd: OPT
do
case $OPT in
"n" ) VALUE_LIMIT="$OPTARG" ;;
"f" ) FLG_FLAT="TRUE" ;;
"d" ) VALUE_START_DATE="$OPTARG" ;;
"h" ) this_ussage ;;
esac
done
#
# body
#
i=0
CUR_DATE="$VALUE_START_DATE"
if [ $FLG_FLAT = "TRUE" ] ; then
echo 'count,ymd,epoch,ymd_bin,md_bin,epoch_bin,ymd_oct,md_oct,epoch_oct,ymd_hex,md_hex,epoch_hex'
else
echo '--------------------'
fi
while [ $i -ne $VALUE_LIMIT ] ;
do
CUR_DATE_YMD=`date -d $CUR_DATE +%Y-%m-%d`
CUR_DATE_EPOCH=`date -d $CUR_DATE +%s`
CUR_DATE_YMD_BIN=`fmt_date 2 "$CUR_DATE" '+%Y%m%d'`
CUR_DATE_MD_BIN=`fmt_date 2 "$CUR_DATE" '+%m%d'`
CUR_DATE_EPOCH_BIN=`fmt_date 2 "$CUR_DATE" '+%s'`
CUR_DATE_YMD_OCT=`fmt_date 8 "$CUR_DATE" '+%Y%m%d'`
CUR_DATE_MD_OCT=`fmt_date 8 "$CUR_DATE" '+%m%d'`
CUR_DATE_EPOCH_OCT=`fmt_date 8 "$CUR_DATE" '+%s'`
CUR_DATE_YMD_HEX=`fmt_date 16 "$CUR_DATE" '+%Y%m%d'`
CUR_DATE_MD_HEX=`fmt_date 16 "$CUR_DATE" '+%m%d'`
CUR_DATE_EPOCH_HEX=`fmt_date 16 "$CUR_DATE" '+%s'`
if [ $FLG_FLAT = "TRUE" ] ; then
echo "$i,$CUR_DATE_YMD,$CUR_DATE_EPOCH,$CUR_DATE_YMD_BIN,$CUR_DATE_MD_BIN,$CUR_DATE_EPOCH_BIN,$CUR_DATE_YMD_OCT,$CUR_DATE_MD_OCT,$CUR_DATE_EPOCH_OCT,$CUR_DATE_YMD_HEX,$CUR_DATE_MD_HEX,$CUR_DATE_EPOCH_HEX"
else
echo -n 'count : '; echo "$i"
echo -n '+%Y-%m-%d : '; echo "$CUR_DATE_YMD"
echo -n '+%s : '; echo "$CUR_DATE_EPOCH"
echo -n '+%Y%m%d -> bin : '; echo "$CUR_DATE_YMD_BIN"
echo -n '+%m%d -> bin : '; echo "$CUR_DATE_MD_BIN"
echo -n '+%s -> bin : '; echo "$CUR_DATE_EPOCH_BIN"
echo -n '+%Y%m%d -> oct : '; echo "$CUR_DATE_YMD_OCT"
echo -n '+%m%d -> oct : '; echo "$CUR_DATE_MD_OCT"
echo -n '+%s -> oct : '; echo "$CUR_DATE_EPOCH_OCT"
echo -n '+%Y%m%d -> hex : '; echo "$CUR_DATE_YMD_HEX"
echo -n '+%m%d -> hex : '; echo "$CUR_DATE_MD_HEX"
echo -n '+%s -> hex : '; echo "$CUR_DATE_EPOCH_HEX"
echo '--------------------'
fi
i=`expr "$i" + 1`
CUR_DATE=`date -d"$VALUE_START_DATE $i"day +%Y%m%d`
done
view raw date2bin.sh hosted with ❤ by GitHub
今回気づいた面白い日付は3/14とか5/12とかでしょうか(今回のコマンド関係ない)。あとはbinary dayくらいですかね。epochで言えば2012/04/02の11時くらいが1333333333でちょっと面白いですね。他にはもう過ぎ去りましたが
$date -d @1234567890 +%Y-%m-%d
$date -d @1111111111 +%Y-%m-%d
とかですか。

ダサいコードで恥ずかしいですが、どんどん晒していきます。


0 件のコメント:

コメントを投稿