[20191101]通过zsh计算sql语句的sql_id.txt
1.简单介绍以及测试使用zsh遇到的问题:
--//前段时间写的,链接http://blog.itpub.net/267265/viewspace-2659623/=>[20191011]通过bash计算sql语句的sql_id.txt
--//bash无法直接实现各种进制的相互转化,我看了bash手册以及上网查一些资料.我发现zsh可以直接实现.
--//例子如下:
zsh$ echo $(( [##32]16#$v2 ))
--//这样可以使用16进制转32进制。v2是16进制数值。
--//很奇怪的是我linux 服务器测试环境,无论bash或者zsh都存在一些小问题.
$ echo $BASH_VERSION
3.2.25(1)-release
--//执行echo "sql_id(32) = $(printf "%013s" $res )"前面的0无法输出。而高版本的bash就没有这个问题。
--//而zsh也是遇到相似的问题,而且zsh无法通过如下模式提取特定位置字符串.例子:
zsh$ v2=${v1:(-16):16}
--//另外执行如下会直接输出{A..V},bash会输出 A B .... V.而输出{0..9}没问题,奇怪.
zsh$ echo {A..V}
{A..V}
% echo {0..9}
0 1 2 3 4 5 6 7 8 9
--//不过我在windows下的Cygwin64测试没有问题.
zsh% echo $ZSH_VERSION
4.2.6
--//不过奇怪的是在windows下的Cygwin64,zsh仅仅最大支持36进制转换.
--//如下在cygwin下执行:
zsh$ echo $(( 63#F ))
zsh: invalid base (must be 2 to 36 inclusive): 63
--//但是在linux下zsh好像编码很奇怪.
% echo $(( 64#z ))
35
% echo $(( 64#Z ))
35
--//大小写zZ输出都是35,我感觉zsh可能最大支持36进制,我当前使用版本不报错罢了.
--//可以确定zsh的编码字符是0-9 A-Z.虽然支持小写输入,但是输出全部是大小字母或者数字.
zsh$ echo $(( [##16]36#F ))
F
zsh$ echo $(( [##16]36#f ))
F
--//有了以上信息,编写转换程序就很容易了.另外你可以完成在bash下调用zsh.只要在开始前写入#! /bin/zsh.当然前提是你已经安装了
--//zsh.
2.补充介绍zsh以及其他shell:
--//一般许多linux发布版本缺省shell都是bash,实际上bash已经变得越来越大,支持功能也越来越多,启动后占用内存也越来越多。这
--//点可以看/bin/bash文件大小可以确定。
--//zsh第一次看到它,我的感觉Z表示英文字符最后一个。也许想成为许多shell的终结者。
--//实际上zsh和bash,我个人的感觉两组开发人员会相互借鉴,我自己个人实在没时间精力学习它。
--//还有一个shell叫fish,我开始以为fi表示finish的意思,实际上Fish 是"the friendly interactive shell"的简称,最大特点就是
--//方便易用。很多其他 Shell 需要配置才有的功能,Fish 默认提供,不需要任何配置。但它的缺点就是与bash兼容性较差。
--//csh(tcsh)现在我估计很少人使用了,就不再介绍。
3.测试:
$ export ODEBUG=1
$ ./sql_id.zsh "select /*+ 12345678abdef */ sysdate from dual "
v1=EF5A2C4876C9E93D0A82FF9604F95E26 v2=A82FF9604F95E26 v3=83451430
sql_text = select /*+ 12345678abdef */ sysdate from dual
full_hash_value(16) = EF5A2C4876C9E93D0A82FF9604F95E26
hash_value(10) = 83451430
sql_id(32) = 0p0rzks2gkrj6
sql_id(32) = p0rzks2gkrj6
--//我的这个版本没有前面输出前面的0。sql_text输出没有后面的的 .
$ ./sql_id.zsh "select * from emp where deptno=10"
v1=8BB974871A4F8C88529EA4885EFE0842 v2=529EA4885EFE0842 v3=1593706562
sql_text = select * from emp where deptno=10
full_hash_value(16) = 8BB974871A4F8C88529EA4885EFE0842
hash_value(10) = 1593706562
sql_id(32) = 557p4j1ggw222
sql_id(32) = 557p4j1ggw222
--//OK,完全能对上.代码看上去更加简洁.贴一个sql_id.sh输出:
$ ./sql_id.sh "select * from emp where deptno=10"
sql_text = select * from emp where deptno=10
full_hash_value(16) = 8BB974871A4F8C88529EA4885EFE0842
hash_value(10) = 1593706562
sql_id = 557p4j1ggw222
4.脚本如下:
$ cat sql_id.zsh
#! /bin/zsh
# calcucate sql_text of full_hash_value(16),hash_value(10),sql_id(32).
odebug=${ODEBUG:-0}
sql_text=${1}' '
v1=$(echo -e -n "$sql_text" | md5sum | sed 's/ -//' | xxd -r -p | od -t x4 | sed -n -e 's/^0+ //' -e 's/ //gp' | tr 'a-z' 'A-Z')
#v2=${v1:(-16):16}
#v3=${v2:(-8):8}
v2=$(echo "obase=16;ibase=16; $v1 % 10000000000000000" | bc| tr -d '\
')
v3=$(echo "obase=10;ibase=16; $v1 % 100000000" | bc| tr -d '\
')
if [ $odebug -eq 1 ] ; then
echo v1=$v1 v2=$v2 v3=$v3
fi
echo "sql_text = $sql_text"
echo "full_hash_value(16) = $v1 "
echo "hash_value(10) = $v3 "
#echo "hash_value(10) = $(( 16#$v3 )) "
#res=$( echo $(( [##32]16#$v2 )) | tr $( echo {0..9} {A..V}| tr -d ' ') $(echo {0..9} {a..z} | tr -d 'eilo ') )
res=$( echo $(( [##32]16#$v2 )) | tr 'ABCDEFGHIJKLMNOPQRSTUV' 'abcdfghjkmnpqrstuvwxyz' )
echo "sql_id(32) = $(printf "%13s" $res | tr ' ' '0')"
echo "sql_id(32) = $(printf "%013s" $res )"
--//bash的脚本:
$ cat sql_id.sh
#! /bin/bash
# calcucate sql_text of full_hash_value(16),hash_value(10),sql_id(32).
odebug=${ODEBUG:-0}
sql_text=${1}' '
v1=$(echo -e -n "$sql_text" | md5sum | sed 's/ -//' | xxd -r -p | od -t x4 | sed -n -e 's/^0+ //' -e 's/ //gp' | tr 'a-z' 'A-Z')
v2=${v1:(-16):16}
v3=${v2:(-8):8}
# v2=$(echo "obase=16;ibase=16; $v1 % 10000000000000000" | bc| tr -d '\
')
# v3=$(echo "obase=10;ibase=16; $v1 % 100000000" | bc| tr -d '\
')
if [ $odebug -eq 1 ] ; then
echo v1=$v1 v2=$v2 v3=$v3
fi
echo "sql_text = $sql_text"
echo "full_hash_value(16) = $v1 "
echo "hash_value(10) = $(( 16#$v3 )) "
BASE32=($(echo {0..9} {a..z} | tr -d 'eilo'))
res=''
for i in $(echo "obase=32;ibase=16; $v2" | bc| tr -d '\
')
do
res=${res}${BASE32[$(( 10#$i ))]}
done
echo "sql_id(32) = $(printf "%13s" $res | tr ' ' '0')"
echo "sql_id(32) = $(printf "%013s" $res)"
res1=$(eval $(echo "obase=32;ibase=16; $v2" | bc| tr -d '\
' | awk 'BEGIN{RS=" +"; printf "echo " }/./{printf "${BASE32[$(( 10#%02d))]} ", $1}' ))
res1=$(tr -d " " <<< $res1)
echo "sql_id(32) = $(printf "%013s" $res1)"