LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1329|回复: 7

已排序key-value文件同key异value多行合并的问题

[复制链接]
发表于 2011-8-22 18:41:54 | 显示全部楼层 |阅读模式
aa 11
aa 22
aa 33
aa 44
bb 55
bb 66
bb 77
cc 88
dd 99

类似这样的,已经排好序的文件,就是key 和 value对,我想要得到的效果是
aa 11 22 33 44
bb 55 66 77
cc 88
dd 99


请问怎样才能做到?
 楼主| 发表于 2011-8-22 20:04:59 | 显示全部楼层
我刚才用了一个办法绕开了:
(1)
  1. awk '{if((a[$1]++)>0)print "henryhj "$2;else print $0}' dstfile > tmpfile
复制代码

(2)vim打开tmpfile,录制宏,宏大概这样

  1. /henryhj
  2. dw
  3. k
  4. J
复制代码

效率也不低,我的文件有30多万行,每次放30000次,放了4次就搞定了,整个也就一两分钟

不过方法显得比较诡异和取巧,继续求正统的解法
回复 支持 反对

使用道具 举报

发表于 2011-8-23 01:14:01 | 显示全部楼层
很久没写perl了,写得不是很好
下面, 两个版本, 一个是没有排序的, 一个是排序的

#!/usr/bin/perl
# not sort
%hash;
while(<>){
        chomp;
        if(/^\s*$/){ next; }
        ($a, $b) = split /\s/, $_, 2;
        push(@{$hash{$a}}, $b);
}

foreach(keys %hash){
        print join(' ', ($_, @{$hash{$_}})) . "\n";
}

#=======================
#sorted
$last = undef;
while(<>){
        chomp;
        if(/^\s*$/){ next; }
        ($a, $b) = split /\s/, $_, 2;
        if($last ne $a){
                print "\n$a";
                $last = $a;
        }
        print " $b"
}
print "\n";
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-8-23 10:16:07 | 显示全部楼层
Post by chasye;2148015
很久没写perl了,写得不是很好
下面, 两个版本, 一个是没有排序的, 一个是排序的

#!/usr/bin/perl
# not sort
%hash;
while(<>){
        chomp;
        if(/^\s*$/){ next; }
        ($a, $b) = split /\s/, $_, 2;
        push(@{$hash{$a}}, $b);
}

foreach(keys %hash){
        print join(' ', ($_, @{$hash{$_}})) . "\n";
}

#=======================
#sorted
$last = undef;
while(<>){
        chomp;
        if(/^\s*$/){ next; }
        ($a, $b) = split /\s/, $_, 2;
        if($last ne $a){
                print "\n$a";
                $last = $a;
        }
        print " $b"
}
print "\n";


受教,我以为应该可以sed或者awk做的,但是这方面比较薄弱

看来还是应该看下perl的

多谢
回复 支持 反对

使用道具 举报

发表于 2011-8-24 21:01:47 | 显示全部楼层
  1. awk '{a[$1]=a[$1]" "$2}END{for (key in a) {print key""a[key]}}'
复制代码
不足之处是输出没排序。
  1. awk '{if (!a[$1]) b[++i]=$1;a[$1]=a[$1]" "$2}END{for (i=1;b[i];i++) {print b[i]""a[b[i]]}}'
复制代码
实现输出排序
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-8-24 21:44:31 | 显示全部楼层
Post by lastart;2148245
...
实现输出排序


多谢

阁下的句子我觉得这句很巧妙,原来是这样迭代的:

  1. a[$1]=a[$1]" "$2
复制代码

很有点
  1. awk '!a[$0]++'
复制代码
的趣味
回复 支持 反对

使用道具 举报

发表于 2011-9-9 20:36:03 | 显示全部楼层
不知道这样可以不?
awk 'NR==1 {var=$1;printf "%s %d",$1,$2};NR!=1 {if ($1!=var) {printf"\n%s %d",$1,$2;var=$1} else {printf " %d",$2}}'  filename
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-9-11 00:35:46 | 显示全部楼层
Post by cool110;2151248
不知道这样可以不?
awk 'NR==1 {var=$1;printf "%s %d",$1,$2};NR!=1 {if ($1!=var) {printf"\n%s %d",$1,$2;var=$1} else {printf " %d",$2}}'  filename


直接处理,非常直观,我看到了C的痕迹
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表