免费注册 查看新帖 |

Chinaunix

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

[文本处理] 求shell/awk/python/perl实现数字级联效果脚本 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2017-09-11 14:38 |只看该作者 |倒序浏览
如有测试数据:
57562        57782
57562         57783
57773         57778
57782         57773
57782         57796
经过处理后得到:
57562->57782->57773->57778
57562->57782->57796
57562->57783

输入测试数据:
57562        57782
57774         57778
57783         57773
经过处理后得到:
57562->57782
57774->57778
57783->57773
求shell/awk/python/perl实现级联效果的脚本。输入数据只有2列,第一列数据可能重复,第二列数据不会重复。

论坛徽章:
0
2 [报告]
发表于 2017-09-11 16:46 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
3 [报告]
发表于 2017-09-11 17:27 |只看该作者
回复 2# 本友会机友会摄友会

第一列为系统资源(如数据库中表上的锁)的拥有者,第二列为系统资源的申请者。当有输入数据时,即表示有锁链产生。此时需要获取此锁链。锁链可能是级联的。如a锁住b,b又锁住c,需要脚本实现a->b->c。请大神指导

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
4 [报告]
发表于 2017-09-12 01:52 |只看该作者
maybe:
  1. #!/usr/bin/perl
  2. use 5.010;

  3. my ( %har, $lista );
  4. while (<DATA>) {
  5.     my ( $dit, $dat ) = split;
  6.     push @$lista, $dit unless $har{$dit};
  7.     push @{ $har{$dit}{lista} }, $dat;
  8. }

  9. rabta();

  10. # ____________________SUB____________________

  11. sub rabta { R_( $lista, 1, [] ) }

  12. sub R_ {
  13.     my ( $lista, $premier, $kolek ) = @_;
  14.     say join ' -> ', @$kolek unless @$lista;

  15.     for my $dit (@$lista) {
  16.         next if $premier and $har{$dit}{bekas};

  17.         if ( !$har{$dit} ) {
  18.             R_( [], 0, [ @$kolek, $dit ] );
  19.         }
  20.         else {
  21.             $har{$dit}{bekas} = 1;
  22.             R_( $har{$dit}{lista}, 0, [ @$kolek, $dit ] );
  23.         }
  24.     }
  25. }

  26. __DATA__
  27. 57562        57782
  28. 57562         57783
  29. 57773         57778
  30. 57782         57773
  31. 57782         57796
复制代码

论坛徽章:
0
5 [报告]
发表于 2017-09-12 09:51 |只看该作者
回复 4# rubyish

功能已实现,能否将脚本函数功能部分放一个单独的脚本?如: cat data.txt |perl test.pl   实在不懂perl脚本,多谢大神。

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
6 [报告]
发表于 2017-09-12 16:36 |只看该作者
回复 1# 乔纳斯826

  1. awk 4.0+
复制代码
  1. awk '{a[$1][$2]}END{for(i in a){for(j in a[i]){if(!(j in o))printf fun(i"->"j,j)}}}function fun(t,n){if(n in a){o[n];for(m in a[n]){t=t"->"m;fun(t,m);t=i"->"j}}else{o[n];print t}}' data
复制代码

论坛徽章:
0
7 [报告]
发表于 2017-09-13 10:46 |只看该作者
回复 6# yinyuemi

多谢大神回复。你的脚本输出为:57782->57796
57782->57773->57778
57562->57782->57796
57562->57782->57773->57778
57562->57783



我还有2个问题:
1. 能否将红色部分去掉呢?因为下面的锁链中已经包含了此部分
2. awk的版本在4.0以上才能执行成功。我的Redhat 6.5上awk版本为3.1。有在awk 3.1版本实现的脚本吗?awk版本升级不方便

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
8 [报告]
发表于 2017-09-13 11:52 |只看该作者
回复 1# 乔纳斯826

$ cat data
57562        57782
57562         57783
57773         57778
57782         57773
57782         57796
57778         57782
57796         57782

$ perl list.pl data
57562 -> 57782 -> 57773 -> 57778 -> 57782(Cycled)
57562 -> 57782 -> 57796 -> 57782(Cycled)
57562 -> 57783

$ cat data1
57562        57782
57774         57778
57783         57773

$ perl list.pl data1
57774 -> 57778
57562 -> 57782
57783 -> 57773

$ cat list.pl
use strict;
use warnings;

my(%hData, %hParent);

while(<>){
  my($sData, $sNext) = split;
  push @{$hData{$sData}}, $sNext;
  $hParent{$sNext} = 1;
}

my %hCycle;
for(keys %hData){
  next if exists $hParent{$_};
  %hCycle = ($_, 1);
  get_next($_, $_);

}

sub get_next{
  my($sKey, $sStr) = @_;
  if(! exists $hData{$sKey}){
    print "$sStr\n";
    return;
  }
  
  foreach(@{$hData{$sKey}}){
    if(exists $hCycle{$_} and $hCycle{$_}){
      print "$sStr -> $_(Cycled)\n";
      next;
    }
    $hCycle{$_} = 1;
    get_next($_, "$sStr -> $_");
    delete $hCycle{$_};
  }
}

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
9 [报告]
发表于 2017-09-13 12:15 |只看该作者
回复 7# 乔纳斯826

  1. echo '57562        57782
  2. 57562         57783
  3. 57773         57778
  4. 57782         57773
  5. 57782         57796' |awk '{a[$1][$2]}END{for(i in a){for(j in a[i]){if(!(j in o))printf fun(i"->"j,j)}}}function fun(t,n){if(n in a){o[n];for(m in a[n]){t=t"->"m;fun(t,m);t=i"->"j}}else{o[n];print t}}'
  6. 57562->57782->57773->57778
  7. 57562->57782->57796
  8. 57562->57783
复制代码
我执行没问题啊,只有三个输出
关于版本问题,你自己编译一下吧

论坛徽章:
0
10 [报告]
发表于 2017-09-13 13:20 |只看该作者
回复 8# jason680

功能完美实现,还有cycle判断,脚本很给力。感谢大神!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP