# cat fxt.a
32353835363030390000050000000c313031
32353830303233349020208020200d313032
怎么样,这样的格式就顺眼多了吧。
生成了中间文件,下一步就应该做正式的数据提取工作了。在实际工作中,很可能原始数据文件中的数据结构和我们需要转换的目标数据结构不完全一致。这时除了提取数据,还要在输出格式上进行一番加工。例如以上的数据文件,如果要按照以下数据结构(Table 2)输出的话,那么就可以参照程序ck1.awk。
Table 2
| 起始位 |
长度 |
说明 |
| 0 |
12 |
账号 |
| 12 |
1 |
, |
| 13 |
1 |
借贷标志,0表示贷,1表示借 |
| 14 |
1 |
, |
| 15 |
14 |
金额 |
| 29 |
1 |
, |
| 30 |
3 |
操作员号 |
# cat ck1.awk
BEGIN{
FS="\n"; }
function trans(s)
{
if((a=substr(s,1,2)-30)<0)
a=0;
for(i=3;i<length(s);i+=2)
{
if((b=substr(s,i,2)-30)<0)
b=0;
a=(a b);
}
return a;
}
{
actno=trans(substr($1,1,16));#帐号
amt=substr($1,17,13);#金额
cdflag=substr($1,30,1); #借贷标志
if(cdflag=="d")
cdflag=1;
if(cdflag=="c")
cdflag=0;
oper=trans(substr($1,31,6));#操作员号
printf("%-12s,%s,%014d,%s\n", actno,cdflag,amt,oper);
}
一个AWK程序分成三个部分,开始,中间处理和结束部分。开始部分用BEGIN{}表示,结束部分用END{}表示,而中间部分用{}围起来即可。BEGIN部分是在正式处理开始之前,做的一些准备工作。而END就是在全部记录都处理完毕之后,做的一些扫尾的工作。
大家可以看到,AWK的语法和C语言很相近,还可以定义函数。而事实上AWK的确在很多地方上都类似于C,所以对C语言有基础的读者应该很快就能掌握AWK的用法。
首先,在开始部分,我们将字段分隔符FS设为\n,就表示将一行作为一个字段来处理。
其次,我们定义了一个函数trans。其功能主要是将用ASCII码方式表示的数字字符给还原成正常的数字形式。数字0-9的ASCII码对应为 30-39。所以要将一个ASCII码转化成对应的数字,只要将该ASCII码减去30即可。例如1的ASCII码为31,那么31 - 30 =1 就很快得出了31所对应的数字。Trans函数正是应用了这一原理,将ASCII码转换成对应的数字,然后将这些数字连接起来,形成账号或者操作员号,返回给调用者。
在正式处理部分,我们大量的运用了substr函数。这是个内置函数,是用于提取字符串中的部分字符。要记住,通过OD的转换之后,我们这里用2位数字代表一个字节。所以账号虽然是8个字节,而我们提取时,要取16个字节。
此外,由于账号和操作员号现在是以ASCII方式表示,所以需要通过trans函数翻译一下。而金额部分由于是直接由16进制ASCII码值来表示了,反倒不用再翻译了。
输出时用到了printf函数。这个函数的用法和标准的C语言printf函数用法完全一样。根据输出数据结构的要求,printf对帐号和金额进行了修饰,使得帐号左对齐且长度为12个字节,用空格对后面不足部分进行填充;而金额部分用前导零填充。
执行以上程序,就得到了我们想要的结果。
# awk -f ck1.awk fxt.a
25856009 ,0,00000050000000,101
25800234 ,1,00000208020200,102