免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: marksman201
打印 上一主题 下一主题

shell排序 [复制链接]

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
61 [报告]
发表于 2010-09-28 18:03 |只看该作者
回复 60# expert1


    如果说有的话,就是awk进行的是字符串比较,而不是数值比较,会出现:
"10.05" < "6.01"的情况。

论坛徽章:
16
IT运维版块每日发帖之星
日期:2015-08-24 06:20:00综合交流区版块每日发帖之星
日期:2015-10-14 06:20:00IT运维版块每日发帖之星
日期:2015-10-25 06:20:00IT运维版块每日发帖之星
日期:2015-11-06 06:20:00IT运维版块每日发帖之星
日期:2015-12-10 06:20:00平安夜徽章
日期:2015-12-26 00:06:302016猴年福章徽章
日期:2016-02-18 15:30:34IT运维版块每日发帖之星
日期:2016-04-15 06:20:00IT运维版块每日发帖之星
日期:2016-05-21 06:20:00综合交流区版块每日发帖之星
日期:2016-08-16 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-14 06:20:00
62 [报告]
发表于 2010-09-29 09:08 |只看该作者
回复 61# blackold


    那数字出现了10.05,3.07这样的,貌似搞不掂吧?

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
63 [报告]
发表于 2010-09-29 10:19 |只看该作者
回复 62# expert1


    方法肯定有的。
  1. awk '{for(i=1;i<=NF;i++){t=$i;sub(/.*:/,"",t);a[t","i]=$i;b[t","i]=t};n=asort(b);for(i=1;i<=n;i++)for(j=1;j<=NF;j++) if(b[i]","j in a) {printf a[b[i]","j]" ";delete a[b[i]","j]}print "";delete a;delete b}' urfile
复制代码
这个可以按数值排序。只是排序,并没有求和,要求和,稍修改即可。

论坛徽章:
16
IT运维版块每日发帖之星
日期:2015-08-24 06:20:00综合交流区版块每日发帖之星
日期:2015-10-14 06:20:00IT运维版块每日发帖之星
日期:2015-10-25 06:20:00IT运维版块每日发帖之星
日期:2015-11-06 06:20:00IT运维版块每日发帖之星
日期:2015-12-10 06:20:00平安夜徽章
日期:2015-12-26 00:06:302016猴年福章徽章
日期:2016-02-18 15:30:34IT运维版块每日发帖之星
日期:2016-04-15 06:20:00IT运维版块每日发帖之星
日期:2016-05-21 06:20:00综合交流区版块每日发帖之星
日期:2016-08-16 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-14 06:20:00
64 [报告]
发表于 2010-09-29 10:27 |只看该作者
回复 63# blackold


    咋整合一起,偶学习学习?

论坛徽章:
0
65 [报告]
发表于 2010-09-29 10:31 |只看该作者
use strict;
use warnings;
while ( my $line = <DATA> ) {
        chomp $line;
        my @lines=split('\s+',$line);
        my %LINE_HASH;
        foreach my $str (@lines) {
                $str=~m#(\w).*)#;
                $LINE_HASH{$1}=$2;
        }
        my $sum=0;
        my @strs;
        foreach my $key (sort {$LINE_HASH{$a} <=> $LINE_HASH{$b}} keys %LINE_HASH) {
                $sum+=$LINE_HASH{$key};
                if($sum>0.5) {
                        $sum-=$LINE_HASH{$key};
                        last;
                }
                push @strs,$key;
        }
        print "$sum\t",scalar @strs,"\t";
        foreach my $str (@strs) {
                print "$strLINE_HASH{$str}\t"
        }
        print "\n";
}

__DATA__
a:0.13 b:0.23 c:0.05 d:0.45 e:0.07
p:0.13 q:0.20 r:0.13 s:0.33 t:0.23
h:0.08 g:0.11 r:0.05 y:0.45 s:0.24
g:0.01 q:0.02 r:0.03 s:0.04 t:0.05
g:0.21 q:0.22 r:0.03 s:0.04 t:0.05
结果
0.48        4        c:0.05        e:0.07        a:0.13        b:0.23       
0.46        3        p:0.13        r:0.13        q:0.20       
0.48        4        r:0.05        h:0.08        g:0.11        s:0.24       
0.15        5        g:0.01        q:0.02        r:0.03        s:0.04        t:0.05       
0.33        4        r:0.03        s:0.04        t:0.05        g:0.21       
这个应该满足吧

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
66 [报告]
发表于 2010-09-29 10:40 |只看该作者
回复 64# expert1


    我晕,就是累加求和啊。
  1. $ awk '{s=0;for(i=1;i<=NF;i++){t=$i;sub(/.*:/,"",t);a[t","i]=$i;b[t","i]=t};n=asort(b);for(i=1;i<=n;i++)for(j=1;j<=NF;j++){t=b[i]","j;if(t in a) {s+=b[i];if(s<0.5)printf a[t]" ";delete a[t]}}print "";delete a;delete b}' urfile
复制代码
里面没有加break,自己优化吧。

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
67 [报告]
发表于 2010-09-29 11:11 |只看该作者
本帖最后由 blackold 于 2010-09-29 11:14 编辑

这种问题还是用perl比较好,写个超难看的
scr.pl

#! /bin/perl

use warnings;
use strict;

while (<>) {
    chomp;
    my @field = split;
    my $s=0;
    @field = sort { (substr $a, (index $a,":")+1) <=> (substr $b, (index $b,":")+1) } @field;
    foreach (@field) {
        $s += substr $_, (index $_,":")+1;
        if($s<0.5) {
            print $_ . " ";
        } else {
            last;
        }
    }
    print "\n";
}

$ perl scr.pl urfile

评分

参与人数 1可用积分 +10 收起 理由
expert1 + 10

查看全部评分

论坛徽章:
16
IT运维版块每日发帖之星
日期:2015-08-24 06:20:00综合交流区版块每日发帖之星
日期:2015-10-14 06:20:00IT运维版块每日发帖之星
日期:2015-10-25 06:20:00IT运维版块每日发帖之星
日期:2015-11-06 06:20:00IT运维版块每日发帖之星
日期:2015-12-10 06:20:00平安夜徽章
日期:2015-12-26 00:06:302016猴年福章徽章
日期:2016-02-18 15:30:34IT运维版块每日发帖之星
日期:2016-04-15 06:20:00IT运维版块每日发帖之星
日期:2016-05-21 06:20:00综合交流区版块每日发帖之星
日期:2016-08-16 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-14 06:20:00
68 [报告]
发表于 2010-09-29 11:18 |只看该作者
回复 66# blackold


    呵呵,不需要break吧

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
69 [报告]
发表于 2010-09-29 11:21 |只看该作者
回复 68# expert1


    看你了,条件满足即退出,没有必要再循环下去了,做无用功。

论坛徽章:
16
IT运维版块每日发帖之星
日期:2015-08-24 06:20:00综合交流区版块每日发帖之星
日期:2015-10-14 06:20:00IT运维版块每日发帖之星
日期:2015-10-25 06:20:00IT运维版块每日发帖之星
日期:2015-11-06 06:20:00IT运维版块每日发帖之星
日期:2015-12-10 06:20:00平安夜徽章
日期:2015-12-26 00:06:302016猴年福章徽章
日期:2016-02-18 15:30:34IT运维版块每日发帖之星
日期:2016-04-15 06:20:00IT运维版块每日发帖之星
日期:2016-05-21 06:20:00综合交流区版块每日发帖之星
日期:2016-08-16 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-14 06:20:00
70 [报告]
发表于 2010-09-29 11:21 |只看该作者
回复 69# blackold


    话说这个还真的比较难,╮(╯▽╰)╭。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP