24小时热门版块排行榜    

北京石油化工学院2026年研究生招生接收调剂公告
查看: 990  |  回复: 4
当前只显示满足指定条件的回帖,点击这里查看本话题的所有回帖

淡蓝幽香

新虫 (初入文坛)

[交流] perl程序继续中,脸红贴上自写程序,求拍砖。 已有2人参与

首先,大力感谢cdtits 同学在另外一个帖子提供的帮助,下面的程序有涉及部分。

本人有如下两个文件:
Doc1
1        NA1        0        0        1
1        NA2        0        0        2
1        295        NA1        NA2        2
1        NA5        0        0        1
1        4        NA5        295        1
1        36        NA6        100        2
1        NA6        0        0        1
1        155        NA6        100        2
1        NA7        4        36        2
2        NA8        0        0        1
2        NA10        0        0        1
2        NA11        0        0        2
2        99        NA8        NA9        2
2        8        NA10        NA11        1
2        390        8        99        1
3        NA12        0        0        1
3        NA13        0        0        2
3        753        NA12        NA13        2
3        NA14        0        0        1
3        9        NA14        753        1
3        NA15        0        0        1
3        NA16        0        0        2
3        186        NA14        753        2
3        722        NA15        NA16        1
3        397        722        186        1
3        396        722        186        1

Doc2
295        2908        2        0      

186        2612        3        1      

722        2827        1        0      

753        8601        3        na      

100        1881        na        na      

4        6358        2        0      

155        4627        2        0      

99        2996        2        0      

1.两个文件的关系:
Doc2中的每一行的第一列数字项,都分别对应Doc1每一行的第二,第三,或者第四列纯数字项。

2.文件特点描述:
所有文件的列之间,都用制表符分隔
Doc1,每一行的第一列都是数字;第二,三,四列可能是数字,也可能是NAi(i代表数字)的组合;第五列是数字或者na。
Doc2,每一行的第一列均为纯数字,最多不超过三位数;第二列也是纯数字,都是固定的四位数;第三列和第四列要么是个位数字,要么就是na。
3.目的:
        在Doc1的每一行第二,三,四列的纯数字项中,分别找到他们各自在Doc2对应数据。用Doc2的第二列数据去取代在Doc1 中的原始数据。要把Doc2 中得最后两项补到Doc1后面。其中这部分的补充决定权在与Doc1的第二列(见另部分例子)。
如:        doc1的第三行:1        295        NA1        NA2        2
         在doc2中对应的行是295        2908        2        0
          结果是:        1        2908        NA1        NA2        2        2(此处用4个制表符分隔)0
另:        doc1        1        4        NA5        295        1;doc2         4        6358        2        0
结果是:        1        6358        NA5        2908        1        2        0

很惭愧地贴上我写的程序,求帮助,求批评,求指正:另外,怎样修改程序,才能让它跑起来更快呢?
use strict;
use warnings;

my $outfile = "o.txt";
open (OUT, ">$outfile"or die("cannot open file";

my $A   = "A.txt";
open(IN, "<$a";

my $C   = "C.txt";
open(C, "<$C";
      
my %code;
my $num = 0;

while (my $l =
{      
                $l =~ s/^\s+//g;
            $l =~ s/\s+$//g;
            next if !length($l);                                               
            my($key, $value) = split (/\t/,$l,2);
            $code{$key} = $value;
}      

close C;
      
my $value;
while (my $line =
{
            $line  =~ s/^\s+//g;
            $line  =~ s/\s+$//g;
            next if !length($line);                                               
             $line =~ /^\d+\t(\w+\d+|\d+)\t(\w+\d+|\d+)\t(\w+\d+|\d+)\t.+/g;
             my ($m1,$m2,$m3)=($1,$2,$3);
           
            for my $key (keys %code)
            {         
                    if ($m1 =~ /^\d+$/ && $key == $m1 )               
                    {
                            my ($v1,$v2) = split(/\t/,$code{$key},2);
                            $line =~ s/$m1/$v1/;
                            my ($d1,$d2) = (/\t/,$v2,2);
                            print OUT "$line\t$d1\t\t\t\t$d2\n";
                    }
                    elsif($m2 =~ /^\d+$/ && $key == $m2)                                    
{
                            my ($v1,$v2) = split(/\t/,$code{$key},2);
                            $line =~ s/$m2/$v1/;
                            print OUT $line."\n";
                    }                     
                    elsif($m3 =~ /^\d+$/ && $key == $m3)                                    
{
                            my ($v1,$v2) = split(/\t/,$code{$key},2);
                            $line =~ s/$m3/$v1/;
                            print OUT $line."\n";
                    }
#头大,写不下去了。。。。错误好多。。。。
           }
}      
        close IN;
close OUT;
回复此楼

» 收录本帖的淘帖专辑推荐

perl语言专栏

» 猜你喜欢

» 本主题相关价值贴推荐,对您同样有帮助:

已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

淡蓝幽香

新虫 (初入文坛)

引用回帖:
3楼: Originally posted by jackie1179 at 2012-07-10 10:42:40
给你写了个,希望能帮到你,另外你有一点说的不是很清楚,如果Doc1的第二列在Doc2中未匹配,而其他列有匹配,要在其后补充吗?本代码不进行补充。

#!/usr/bin/perl -w

unless (@ARGV) {
  die "Argumen ...

非常感谢哦。

关于你提到的:Doc1的第二列在Doc2中未匹配,而其他列有匹配,要在其后补充吗?

这个不用补充,只有Doc1第一列,在找到Doc2中的匹配项后, 需要补充。Doc1的其他列都不用
5楼2012-07-10 19:49:53
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
查看全部 5 个回答

anntoy

木虫 (著名写手)

★ ★
小木虫: 金币+0.5, 给个红包,谢谢回帖
xzhdty: 金币+1, 谢谢参与 2012-07-10 15:41:59
代码应该写在代码块里
也就是
CODE:
[code]、

[/code]之间
2楼2012-07-10 08:38:14
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

jackie1179

木虫 (正式写手)

★ ★ ★
小木虫: 金币+0.5, 给个红包,谢谢回帖
xzhdty: 金币+2, 谢谢参与 2012-07-10 15:42:21
给你写了个,希望能帮到你,另外你有一点说的不是很清楚,如果Doc1的第二列在Doc2中未匹配,而其他列有匹配,要在其后补充吗?本代码不进行补充。
CODE:
#!/usr/bin/perl -w

unless (@ARGV) {
  die "Arguments not enough!";
}

$doc1 = $ARGV[0];
$doc2 = $ARGV[1];
undef %string;
open(DOC2,"$doc2") || die "Cannot open this file!$!";
while() {
  next if(/^\n/);
  chomp;
  
  @array = split /\t/;
  $string{$array[0],2} = $array[1];
  $string{$array[1],3} = $array[2];
  $string{$array[1],4} = $array[3];
}
close DOC2;


open(DOC1,"$doc1") || die "Cannot open this file!$!";
$out = "output";
open(OUT,">$out") || die "Cannot write to this file!$!";
while() {

  chomp;
  @array = split /\t/;
  print $array[2],"=>",&isPureDigit($array[2]),"\n";
  $mark = 0;
  foreach $i(1 .. 3) {
    if(&isPureDigit($array[$i]) && defined $string{$array[$i],2}) {
      if($i == 1) { $mark = 1; }
      $array[$i] = $string{$array[$i],2};
    }
  }
  foreach (@array) {
    print OUT "$_\t";
  }
  if($mark == 1) {
    print OUT "$string{$array[1],3}\t\t\t\t$string{$array[1],4}";
  }
  print OUT "\n";

}

close DOC1;
close OUT;

sub isPureDigit {
  $arg = shift;
  if($arg =~ /^NA/) {
    return 0;
  } else {
    return 1;
  }  
}

3楼2012-07-10 10:42:40
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

jackie1179

木虫 (正式写手)


小木虫: 金币+0.5, 给个红包,谢谢回帖
不好意思,忘了说用法:
保存为文件pro.pl
perl  ./pro.pl  doc1 doc2
输出文件名为 output
4楼2012-07-10 10:44:45
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
普通表情 高级回复 (可上传附件)
最具人气热帖推荐 [查看全部] 作者 回/看 最后发表
[考研] 282求调剂 不挑专业 求收留 +4 Yam. 2026-03-30 5/250 2026-03-31 14:41 by 王亮_大连医科大
[考研] 086000调剂 +4 7901117076 2026-03-26 4/200 2026-03-31 14:30 by 记事本2026
[考研] 土木304求调剂 +3 顶级擦擦 2026-03-31 3/150 2026-03-31 13:59 by 西京学院招办
[考研] 080500-315分复试调剂 +4 上岸3821 2026-03-31 4/200 2026-03-31 13:06 by oooqiao
[考研] 学硕274求调剂 +16 Li李鱼 2026-03-26 16/800 2026-03-31 12:27 by 无际的草原
[考研] 294分080500材料科学与工程求调剂 +9 柳溪边 2026-03-26 9/450 2026-03-31 12:16 by oooqiao
[论文投稿] chinese chemical letters英文版投稿求助 130+3 Yishengeryi 2026-03-30 3/150 2026-03-31 10:10 by 北京莱茵润色
[考研] 085600材料与化工调剂 +16 kikiki7 2026-03-30 16/800 2026-03-31 10:03 by 氯化亚硝酰
[考研] 物理学调剂 +3 小羊36 2026-03-30 3/150 2026-03-31 09:20 by jp9609
[考研] 材料与化工调剂一志愿大连海事085600,349 +6 吃的不少 2026-03-30 6/300 2026-03-31 04:17 by fmesaito
[考研] 293求调剂 +3 末未mm 2026-03-30 5/250 2026-03-30 17:23 by 王保杰33
[考研] 329求调剂,一志愿西北工业大学,材料工程(085601) +5 小小机灵虫 2026-03-29 11/550 2026-03-30 15:02 by Wang200018
[考研] 284求调剂 +14 junqihahaha 2026-03-26 15/750 2026-03-30 14:12 by 探123
[考研] 一志愿中南大学化学0703总分337求调剂 +6 niko- 2026-03-27 6/300 2026-03-30 10:25 by herarysara
[考研] 316求调剂 +7 江辞666 2026-03-26 7/350 2026-03-28 21:28 by sanrepian
[考研] 药学105500求调剂 +3 Ssun。。 2026-03-28 3/150 2026-03-28 11:24 by lxf170613
[考研] 266求调剂 +11 阳阳哇塞 2026-03-27 12/600 2026-03-27 17:56 by yu221
[考研] 调剂求收留 +7 果然有我 2026-03-26 7/350 2026-03-27 00:26 by wxiongid
[考研] 网络空间安全0839招调剂 +4 w320357296 2026-03-25 6/300 2026-03-25 17:59 by 255671
[考研] 302求调剂 +4 锦衣卫藤椒 2026-03-25 4/200 2026-03-25 16:29 by 功夫疯狂
信息提示
请填处理意见