Chinaunix首页 | 论坛 | 博客
  • 博客访问: 377231
  • 博文数量: 61
  • 博客积分: 2451
  • 博客等级: 上尉
  • 技术积分: 650
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-06 21:24
文章分类

全部博文(61)

文章存档

2012年(1)

2011年(44)

2010年(16)

分类: LINUX

2011-06-07 23:02:51

文本:
  1. A 001 10
  2. A 002 20
  3. A 003 30
  4. B 004 40
  5. B 005 50
  6. C 006 60
  7. C 007 70
  8. D 008 80
  9. E 009 90
  10. E 010 100
要想得到的结果:
  1. A AA B BB C CC D DD E EE
  2. 001 10 004 40 006 60 008 80 009 90
  3. 002 20 005 50 007 70 010 100
  4. 003 30
perl 的代码(先贴下):
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;
  4. my (%a,%b,%c);
  5. my $ml=0;
  6. open (TEST,") or die "can't open file a";
  7. while(<TEST>){
  8.         my($c1,$c2,$c3)=split;
  9.         $c{$c1}++;
  10.         $a{$c1,$c{$c1}}=$c2;
  11.         $b{$c1 x 2,$c{$c1}}=$c3;
  12.         $ml=$ml>$c{$c1}?$ml:$c{$c1};
  13. }
  14. foreach (sort keys %c){
  15.         print $_,"\t";
  16.         print $_ x 2,"\t";
  17. }
  18. print "\n";
  19. for (my $i=1;$i<=$ml;$i++){
  20.         foreach (sort keys %c){
  21.                 unless($a{$_,$i}){
  22.                 print "\t";
  23.         }else{
  24.                 print $a{$_,$i},"\t";
  25.         }
  26.                 unless ($b{$_ x 2,$i}){
  27.                 print "\t";
  28.         }else{
  29.                 print $b{$_ x 2,$i},"\t";
  30.         }
  31.         }
  32.         print "\n";
  33. }
数据结构:
  1. $VAR1 = {
  2. 'E2' => '010',
  3. 'A2' => '002',
  4. 'E1' => '009',
  5. 'C2' => '007',
  6. 'D1' => '008',
  7. 'B1' => '004',
  8. 'A3' => '003',
  9. 'B2' => '005',
  10. 'C1' => '006',
  11. 'A1' => '001'
  12. };
  13. $VAR2 = {
  14. 'EE1' => '90',
  15. 'EE2' => '100',
  16. 'BB2' => '50',
  17. 'CC1' => '60',
  18. 'AA2' => '20',
  19. 'BB1' => '40',
  20. 'DD1' => '80',
  21. 'AA1' => '10',
  22. 'AA3' => '30',
  23. 'CC2' => '70'
  24. };
  25. $VAR3 = {
  26. 'A' => 3,
  27. 'D' => 1,
  28. 'C' => 2,
  29. 'E' => 2,
  30. 'B' => 2
  31. };
简单说明:
awk 的代码:
  1. #!/bin/gawk -f
  2. {
  3. c[$1]++;
  4. a[$1,c[$1]]=$2;
  5. b[$1,$1,c[$1]]=$3;
  6. ml=ml>c[$1]?ml:c[$1];
  7. }
  8. END{
  9. n=asorti(c);
  10. for(i=1;i<=n;i++)
  11. {
  12. printf "%s\t",c[i];
  13. printf "%s%s\t",c[i],c[i];
  14. }
  15. printf "\n";
  16. for(j=1;j<=ml;j++)
  17. {
  18. for(i=1;i<=n;i++)
  19. {
  20. if(a[c[i],j]){
  21. printf "%s\t",a[c[i],j];
  22. }else{
  23. printf "\t";
  24. }
  25. if(b[c[i],c[i],j]){
  26. printf "%s\t",b[c[i],c[i],j];
  27. }else{
  28. printf "\t";
  29. }
  30. }
  31. printf "\n";
  32. }
  33. }
其实和perl一样 只是用awk的语法写了一遍。
说下思路:
因为从输出结果中看出来A,B...等重复了几行,及那个最大最后输出就有几行,这里用了ml记录最大行数。同时分别用hash a 和 b 存放第二个域与第三个域 接下来就是排序输出的问题了awk 和 perl用的函数不一样 分别是asorti 和 sort
这里asorti 和asort 要注意区别
前面是对index 进行排序。排完后index 变成1-n(n是返回值 即hash/数组元素个数) 值变成了原来的index,只不过这里已经排好序了。比如A在B前面 则a[1]=A a[2]=B 如果不想失去原来的hash的话 只要加一个目的hash就行了。
asorti(source_array,dest_array)
awk 会先将source_array 中的数组拷贝到dest_array 中去然后进行如上面所说的排序。asort 针对的是值的排序。排好好index 也变成1-n的形式
同样可以加dest_array 避免source_array 中的index消失。




阅读(2524) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~