免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5294 | 回复: 9
打印 上一主题 下一主题

【用shell实现二维表格】 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-20 14:07 |只看该作者 |倒序浏览
从数据库取出三列数据:

籍贯        所在省份        人数
上海人        北京        120
广东人        广东        320
吉林人        湖北        120
上海人        四川        80
四川人        江苏        20
湖南人        湖北        20
四川人        四川        40
广西人        北京        60
江西人        北京        70
四川人        广东        80
湖南人        四川        45
湖北人        湖南        36
四川人        湖南        78
.        .        .
.        .        .
.        .        .
.        .        .


希望用shell实现输出一个二维表格(表格用html代码):

        上海人        广东人        吉林人        四川人        广西人        湖南人        江西        湖北人
北京        120        0        0        0        60        0        70        0
广东        0        320        0        80        0        0        0        0
湖北        0        0        120        0        0        20        0        0
四川        80        0        0        40        0        45        0        0
江苏        0        0        0        20        0        0        0        0
湖南        0        0        0        78        0        0        0        36


由于籍贯和所在省份不是一个固定的数字,所以有些伤脑筋,待达人。

[ 本帖最后由 AmboLong 于 2009-3-20 14:09 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-03-20 14:10 |只看该作者
把每行输出到while循环内的一个变量里

然后提取这个变量的不同字段,中间加上合适的html代码好了

论坛徽章:
0
3 [报告]
发表于 2009-03-20 14:23 |只看该作者

回复 #2 welcome008 的帖子

能否写个代码,感谢。

论坛徽章:
0
4 [报告]
发表于 2009-03-20 15:16 |只看该作者
试着写个perl的:
#!/usr/bin/perl
while(<>){
        chomp;
        ($home,$now,$count)=split;
        $home{$home}++;
        $now{$now}->{$home}=$count;
}
$,="\t";
print "\t",keys %home,"\n";
for $now (keys %now){
        print $now,"\t";
        for $home (keys %home){
                if(exists $now{$now}->{$home}){
                        print "$now{$now}->{$home}\t";
                }else{
                        print "0\t"
                }
        }
        print "\n";
}

版主说的是,有了思路,实现起来就容易:
awk 'NR>1{home[$1]++;now[$2]++;count[$1""$2]=$3}END{printf "\t";for(j in home){printf j"\t";}print "";for(k in now){printf k"\t";for(j in home){printf count[j""k]+0"\t";}print "";}}' file

[ 本帖最后由 dream3401 于 2009-3-20 17:03 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2009-03-20 16:10 |只看该作者

回复 #4 dream3401 的帖子

不错,期待shell的版本,供大家学习。

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
6 [报告]
发表于 2009-03-20 16:38 |只看该作者

回复 #5 AmboLong 的帖子

什么版的不都就是个循环打印么?


  1. awk 'NR>1{if(!a[$1]++)ai[i++]=$1;if(!b[$2]++)bi[j++]=$2;c[$1,$2]=$3}
  2. END{for(m=0;m<i;m++)printf "\t"ai[m];print ""
  3. for(n=0;n<j;n++){printf bi[n];for(m=0;m<i;m++)printf "\t"c[ai[m],bi[n]]+0;print ""}}' urfile
复制代码

论坛徽章:
0
7 [报告]
发表于 2009-03-20 16:58 |只看该作者

回复 #6 waker 的帖子

版主一出手就知有没有。。

论坛徽章:
0
8 [报告]
发表于 2009-03-20 18:10 |只看该作者
发现一个问题,籍贯这一列存在为空的行。也就是如下:

籍贯        所在省份        人数
上海人        北京        120
              广东        320
广东人        广东        320
吉林人        湖北        120
上海人        四川        80
四川人        江苏        20
湖南人        湖北        20
四川人        四川        40
广西人        北京        60
江西人        北京        70
四川人        广东        80
湖南人        四川        45
湖北人        湖南        36
四川人        湖南        78
.        .        .
.        .        .
.        .        .
.        .        .

当籍贯为空希望输出的二维表格的空列字段,也就是说把空籍贯当种一类籍贯输出。脚本需要如何改呢?因为发现如果有籍贯为空的列,原先的脚本会影响整个输出。

        上海人        广东人        吉林人        四川人        广西人        湖南人        江西        湖北人    NULL
北京        120        0        0        0        60        0        70        0       0
广东        0        320        0        80        0        0        0        0         320
湖北        0        0        120        0        0        20        0        0         0
四川        80        0        0        40        0        45        0        0         0
江苏        0        0        0        20        0        0        0        0             0
湖南        0        0        0        78        0        0        0        36           0

[ 本帖最后由 AmboLong 于 2009-3-20 18:15 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2009-03-20 20:02 |只看该作者
未完待顶

论坛徽章:
0
10 [报告]
发表于 2009-03-20 20:13 |只看该作者
如果有一行只有两个字段,并且缺少的是第一个字段,就是哪里人的话,可以这样:
awk 'NR>1{if(NF==2){$3=$2;$2=$1;$1="NULL";}home[$1]++;now[$2]++;count[$1""$2]=$3}END{printf "\t";for(j in home){printf j"\t";}print "";for(k in now){printf k"\t";for(j in home){printf count[j""k]+0"\t";}print "";}}' file

或是将我上面写的perl改一下:
#!/usr/bin/perl
while(<>){
        next if $.==1;
        chomp;
        ($home,$now,$count)=split;
        ($home,$now,$count)=("NULL",$home,$now) unless $count;        $home{$home}++;
        $now{$now}->{$home}=$count;
}
$,="\t";
print "\t",keys %home,"\n";
for $now (keys %now){
        print $now,"\t";
        for $home (keys %home){
                if(exists $now{$now}->{$home}){
                        print "$now{$now}->{$home}\t";
                }else{
                        print "0\t"
                }
        }
        print "\n";
}

[ 本帖最后由 dream3401 于 2009-3-20 20:20 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP