Chinaunix

标题: 请教高手,看这个shell怎么写? [打印本页]

作者: qcgxlg    时间: 2008-06-20 17:10
标题: 请教高手,看这个shell怎么写?
原始文件格式是这样的:


20080525|0600|758836152.12
20080525|0602|609000.00
20080525|0603|2666746080.44
20080525|0604|1400500000.00
20080525|0605|380000000.00
20080525|0606|356894829.48

想把上面格式的文件转换为:


   交易日期           0600                  0602           0603           0604                0605                   0606
   20080525     758836152.12    609000.00  2666746080.44   1400500000.00   380000000.00   356894829.48

请问该如何处理?谢谢!!!

[ 本帖最后由 qcgxlg 于 2008-6-20 17:11 编辑 ]
作者: opiopuiopoi    时间: 2008-06-20 17:45
标题: 回复 #1 qcgxlg 的帖子
研究中。。。。
如果数据变成这样:
20080525|0600|758836152.12
20080525|0602|609000.00
20080525|0603|2666746080.44
20080525|0604|1400500000.00
20080525|0605|380000000.00
20080525|0606|356894829.48
20080525|0600|758836152.12
20080526|0602|609000.00
20080526|0603|2666746080.44
20080526|0604|1400500000.00
20080526|0605|380000000.00
20080526|0606|356894829.48

考虑结果为:
交易日期           0600                  0602           0603           0604                0605                   0606
20080525     758836152.12    609000.00  2666746080.44   1400500000.00   3800000.00   35689489.48
20080526     758836152.12    609000.00  2666746080.44   1400500000.00   3800000.00   35689489.48
作者: qcgxlg    时间: 2008-06-20 18:00
标题: 回复 #2 opiopuiopoi 的帖子
谢谢,楼上说的对,有可能是多个交易日期,期待中.......
作者: qcgxlg    时间: 2008-06-20 18:08
标题: 回复 #1 qcgxlg 的帖子
先顶一下..................
作者: walkerxk    时间: 2008-06-20 18:22
感觉awk可以处理,可惜我awk不行。
作者: qcgxlg    时间: 2008-06-20 18:26
标题: 回复 #1 qcgxlg 的帖子
这里的高手很多,应该是可以解决的,现实工作中经常遇到这样的问题,谢谢各位大侠的指点,不管用什么办法,能转换就行,感谢!!
作者: qcgxlg    时间: 2008-06-20 18:31
标题: 回复 #2 opiopuiopoi 的帖子
原始数据是select语句从数据库中得到的,不知道用sql语句是否能够实现这样的输出?
作者: merlin852    时间: 2008-06-20 18:36
awk -F\| '{a[$1]++;b[$2]=$2;c[$1]=c[$1]"\t"$3;if(a[$1]==1)c[$1]="\n"$1"\t"c[$1]}END{printf "交易日期  ";for(i in b)printf"%s\t\t", i;printf"\n";for(j in c) print  c[j]}'

先撮合的用下吧,应该有更简单的了


[ 本帖最后由 merlin852 于 2008-6-23 08:24 编辑 ]
作者: qcgxlg    时间: 2008-06-20 18:37
标题: 回复 #8 merlin852 的帖子
谢谢,试一下
作者: cpfly    时间: 2008-06-20 18:44
楼上的数据有点小问题,其中,第二个0525的0600,应该是0526的:
20080525|0600|758836152.12
20080525|0602|609000.00
20080525|0603|2666746080.44
20080525|0604|1400500000.00
20080525|0605|380000000.00
20080525|0606|356894829.48
20080526|0600|758836152.12
20080526|0602|609000.00
20080526|0603|2666746080.44
20080526|0604|1400500000.00
20080526|0605|380000000.00
20080526|0606|356894829.48


  1. awk -F'|' 'BEGIN { date1="" }  { if ( $1 != date1 ) { if(NR != 1) print x"\n"y; x="date\t\t"$2; y=$1"\t"$3; date1=$1} else { x=x"\t\t"$2; y=y"\t"$3}  } END {print x"\n"y}' 0620.txt
复制代码


结果:
date            0600            0602            0603            0604            0605            0606
20080525        758836152.12    609000.00       2666746080.44   1400500000.00   380000000.00    356894829.48
date            0600            0602            0603            0604            0605            0606
20080526        758836152.12    609000.00       2666746080.44   1400500000.00   380000000.00    356894829.48

或者

  1. awk -F'|' 'BEGIN { date1=""; tf=0 }  { if ( $1 != date1 ) { if(NR != 1) { if(tf==0) {print x; tf=1} print y} x="date\t\t"$2; y=$1"\t"$3; date1=$1} else { x=x"\t\t"$2; y=y"\t"$3}  } END {print y}' 06202.txt
复制代码


结果:
date            0600            0602            0603            0604            0605            0606
20080525        758836152.12    609000.00       2666746080.44   1400500000.00   380000000.00    356894829.48
20080526        758836152.12    609000.00       2666746080.44   1400500000.00   380000000.00    356894829.48

希望对你有帮助。。。
作者: qcgxlg    时间: 2008-06-20 18:57
标题: 回复 #10 cpfly 的帖子
谢谢,我运行的结果是这样的,请帮忙看一下:

  
date              0600          0602               0603                 0604              0605                 0606            0600
20080525 758836152.12 609000.00  2666746080.44 1400500000.00 380000000.00 356894829.48 758836152.12
20080526 609000.00    2666746080.44  1400500000.00 380000000.00  356894829.48

作者: qcgxlg    时间: 2008-06-20 19:00
标题: 回复 #8 merlin852 的帖子
报错:

交易日期  awk: cmd. line:1: (FILENAME=cd.txt FNR=12) fatal: attempt to use array `b' in a scalar context
作者: merlin852    时间: 2008-06-20 19:08
漏了b
作者: qcgxlg    时间: 2008-06-20 19:10
原帖由 merlin852 于 2008-6-20 19:08 发表
漏了b

正确的应该怎么写?谢谢
作者: ly5066113    时间: 2008-06-20 19:52
原帖由 qcgxlg 于 2008-6-20 18:31 发表
原始数据是select语句从数据库中得到的,不知道用sql语句是否能够实现这样的输出?


写sql感觉会简单一些。
假设你的数据中的3个列为:
   col1       col2          col3
20080525|0600|758836152.12


select
col1
sum(case when col2 = "0600" then col3 else 0 end)
sum(case when col2 = "0601" then col3 else 0 end)
sum(case when col2 = "0602" then col3 else 0 end)
sum(case when col2 = "0603" then col3 else 0 end)
sum(case when col2 = "0604" then col3 else 0 end)
sum(case when col2 = "0605" then col3 else 0 end)
sum(case when col2 = "0606" then col3 else 0 end)
from table
group by col1
作者: springwind426    时间: 2008-06-20 20:23

  1. awk -F'|' '{d[$1]=1;n[$1,$2]=$3;h[$2]=1}
  2. END{
  3. printf "交易日期"; for(j in h){printf "%16s",j};print "";
  4. for(i in d){printf i;for(j in h)printf "%16s",n[i,j];print ""}
  5. }' 数据文件
复制代码

作者: liaosnet    时间: 2008-06-20 21:09
原帖由 ly5066113 于 2008-6-20 19:52 发表


写sql感觉会简单一些。
假设你的数据中的3个列为:
   col1       col2          col3
20080525|0600|758836152.12


select
col1
sum(case when col2 = "0600" then col3 else 0 end)
sum(case w ...


嗯...在SQL里这样写..
作者: cpfly    时间: 2008-06-21 01:24
标题: 回复 #11 qcgxlg 的帖子
哦,这个我说过了,就是数据的问题,你可以看到 0526那个日期的数据,有2个0600的。。
作者: opiopuiopoi    时间: 2008-06-22 16:35
嗯,学习了,用二维数组。感谢高手们!
作者: smz0102    时间: 2008-06-22 17:53
awk 太强了,学些中
作者: bluebit    时间: 2008-06-22 18:41
标题: 另一个实现
增强了对输入数据格式支持,以及输出样式控制:

function echo_result(date,NUM,QUOTE){
    printf "\n%-15s",date;
    for(i=0 ; i<length(NUM) ;i+=1 ){
        qu=QUOTE[NUM];
        if(qu>0)
            printf "%-15.2f ",qu;
        else
            printf "%-16s","NAN";
    }   
}

begin{
    c=0;
}   

{
    if($1==date || NR==1)
    {   
        if(c==0){
            NUM[NR-1]=$2;
        }   
    }else{
        c++;   
        if(c==1){
            printf "%-15s","quote";
            for(i=0 ; i<length(NUM) ;i+=1 ){
                printf "%-15s ",NUM;
            }   
        }   
        echo_result(date,NUM,QUOTE);
        delete QUOTE;

    }   
    QUOTE[$2]=$3;
    date=$1;
}   

END{
        echo_result(date,NUM,QUOTE);
}

执行:
awk -F'\' -f quote.awk quote.dat
输入quote.dat:
20080525|0600|758836152.12
20080525|0602|609000.00
20080525|0603|2666746080.44
20080525|0604|1400500000.00
20080525|0605|380000000.00
20080525|0606|356894829.48
20080526|0603|2666746080.42
20080526|0602|609000.05
20080526|0604|1400500000.07
20080526|0605|380000000.09
20080526|0606|356894829.41

输出:
quote          0600            0602            0603            0604            0605            0606            
20080525       758836152.12    609000.00       2666746080.44   1400500000.00   380000000.00    356894829.48   
20080526       NAN             609000.05       2666746080.42   1400500000.07   380000000.09    356894829.41
作者: qcgxlg    时间: 2008-06-23 08:57
谢谢,太好了.学习了!




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2