perl to loop and check across files -
still having trouble perl programming , need pushed make script work out. have 2 files , want use list file "extract" rows data one. problem list file formatted follow:
x1 b x2 c d x3 e f and data looks this:
a x1 2 5 b x1 3 7 c x2 1 4 d x2 1 5 i need obtain element pairs list file select row in data file. @ same time write output this:
x1 b 2 5 3 7 x2 c d 1 4 1 5 i'm trying writing perl code, i'm not able produce useful. i'm @ point:
open (list, "< $fils_list") || die "impossibile open list"; @list = <list>; close (list); open (han, "< $data") || die "impossible open data"; @r = <han>; close (han); ($p=0; $p<=$#list; $p++){ chomp ($list[$p]); ($x, $id1, $id2) = split (/\t/, $list[$p]); $pair_one = $id1."\t".$x; $pair_two = $id2."\t".$x; ($i=0; $i<=$#r; $i++){ chomp ($r[$i]); ($a, $b, $value1, $value2) = split (/\t/, $r[$i]); $bench = $a."\t".$b; if (($pair_one eq $bench) || ($pair_two eq $bench)){ print "i don't know script must print!\n"; } } } i'm not able rationalize print. kind of suggestion welcome!
a few general recommendations:
- indent code show structure of program.
- use meaningful variable names, not
$aor$value1(if below, due lack of domain knowledge). - use data structures suit program.
- don't operations parsing line more once.
- in perl, every program should
use strict; use warnings;. use autodieautomatic error handling.
also, use open function open $fh, "<", $filename safer.
remember said data structures? in second file, have entries like
a x1 2 5 this looks secondary key, primary key, , data columns. key-value relationships best expressed through hash table.
use strict; use warnings; use autodie; use feature 'say'; # available since 5.010 open $data_fh, "<", $data; %data; while (<$data_fh>) { chomp; # remove newlines ($id2, $id1, @data) = split /\t/; $data{$id1}{$id2} = \@data; } now %data nested hash can use easy lookups:
open $list_fh, "<", $fils_list; line: while(<$list_fh>) { chomp; ($id1, @id2s) = split /\t/; $data_id1 = $data{$id1}; defined $data_id1 or next line; # maybe there isn't here. skip @values = map @{ $data_id1->{$_} }, @id2s; # map 2nd level ids values , flatten list # print out: join "\t", $id1, @id2s, @values; } the map function bit foreach loop, , builds list of values. need @{ ... } here because data structure doesn't hold arrays, references arrays. @{ ... } dereference operator.
Comments
Post a Comment