LinuxSir.cn,穿越时空的Linuxsir!

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

shell如何处理这类数据

[复制链接]
发表于 2009-12-14 17:27:57 | 显示全部楼层 |阅读模式
shell新人,请教各位大牛,本人有如下数据:
qeri   22:46
aaaa   01:03
bbbb   56:23
ekjd   01:03
fqkl   56:23
fakq   56:23

这里想以第一列为依据,当数据相同时,合并各自的第一列数据,最后结果为

qeri             22:46
aaaa/ekjd        01:03
bbbb/fqkl/fakq   56:23

想了很久,都没能写出来,请教一下,谢谢!
发表于 2009-12-14 19:53:46 | 显示全部楼层
  1. function merge() {
  2. declare -a result;
  3. declare -a timeArray;
  4. set i=1;
  5. while read name time;
  6. do
  7.         index=${time##*:}${time%%:*}
  8.         if [ -z "${result[$index]}" ]; then
  9.                 result[$index]=$name;
  10.                 timeArray[$i]=$time;
  11.                 i=$((i+1));
  12.         else
  13.                 result[$index]=${result[$index]}"/"$name;
  14.         fi
  15. done;
  16. for ((j = 1; j < i; j ++))
  17. do
  18.         time=${timeArray[$j]};
  19.         index=${time##*:}${time%%:*};
  20.         [ -z "${result[$index]}" ] || echo ${result[$index]} $time;
  21. done;
  22. }

  23. merge << EOF
  24. qeri 22:46
  25. aaaa 01:03
  26. bbbb 56:23
  27. ekjd 01:03
  28. fqkl 56:23
  29. fakq 56:23
  30. EOF
复制代码
回复 支持 反对

使用道具 举报

发表于 2009-12-14 20:10:28 | 显示全部楼层
传说中的人物用AWK。。。
  1. awk '{
  2.     if(length(a[$2]) > 0)
  3.     {a[$2] = (a[$2] "/" $1);}
  4.     else
  5.         {a[$2] = $1;}
  6. }
  7. END{
  8.     for(i in a){print a[i],i;}
  9. }'  $YOURFILE
复制代码
回复 支持 反对

使用道具 举报

发表于 2009-12-14 20:10:30 | 显示全部楼层
这样?
awk '{a[$2]=a[$2]"/"$1}END{for(i in a)print a,i}' dataFile
回复 支持 反对

使用道具 举报

发表于 2009-12-14 22:16:17 | 显示全部楼层
你把第二列当成关键字,做个hash,把结果串起来,O(n)复杂度,比较快
回复 支持 反对

使用道具 举报

发表于 2009-12-15 08:17:07 | 显示全部楼层
perl:

  1. while(<>){
  2. my ($val, $key) = split ' ',$_;
  3. push @{$hash{$key}}, $val;
  4. }

  5. foreach(keys %hash){
  6.         my %tmp;
  7.         my @outlist = grep !$tmp{$_}++, @{$hash{$_}};
  8.         print join '/',@outlist;
  9.         print " $_\n";
  10. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-12-15 10:52:31 | 显示全部楼层
Post by tomgrean;2055888
传说中的人物用AWK。。。
  1. awk '{
  2.     if(length(a[$2]) > 0)
  3.     {a[$2] = (a[$2] "/" $1);}
  4.     else
  5.         {a[$2] = $1;}
  6. }
  7. END{
  8.     for(i in a){print a[i],i;}
  9. }'  $YOURFILE
复制代码



这个方法很巧妙,比我想的简单多了,学习了!谢谢!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-12-15 10:57:17 | 显示全部楼层
Post by chasye;2055980
perl:

  1. while(<>){
  2. my ($val, $key) = split ' ',$_;
  3. push @{$hash{$key}}, $val;
  4. }

  5. foreach(keys %hash){
  6.         my %tmp;
  7.         my @outlist = grep !$tmp{$_}++, @{$hash{$_}};
  8.         print join '/',@outlist;
  9.         print " $_\n";
  10. }
复制代码



perl还没开始看,这里做个记号,以后回来看,也谢谢了!
回复 支持 反对

使用道具 举报

发表于 2009-12-15 12:53:03 | 显示全部楼层
awk 果然强大。。。向传说中的人物学习。。。
回复 支持 反对

使用道具 举报

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

本版积分规则

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