0

次のことを行うスクリプトを書きたいと思います: ユーザーは .txt ファイルをインポートすることを選択できます (このためにコードを書きました)(こちら$list1)。このファイルは、各行に名前を持つ 1 つの列のみで構成されます。ユーザーが空ではないファイルをインポートした場合、別のファイル (ここで$file2は) の列の名前をインポートされたファイルの名前と比較します。一致する場合は、この元のファイル ( ) の行全体を$file2新しいファイル ( $filter1) に配置する必要があります。

これは私がこれまでに持っているものです:

my $list1;

if (prompt_yn("Do you want to import a genelist for filtering?")){
    my $genelist1 = prompt("Give the name of the first genelist file:\n");
    open($list1,'+<',$genelist1) or die "Could not open file $genelist1 $!";
}

open(my $filter1,'+>',"filter1.txt") || die "Can't write new file: $!";

my %hash1=();
while(<$list1>){ # $list1 is the variable from the imported .txt file
    chomp;    
    next unless -z $_;
    my $keyfield= $_; # this imported file contains only one column
    $hash1{$keyfield}++;
}

seek $file2,0,0; #cursor resetting
while(<$file2>){ # this is the other file with multiple columns
    my @line=split(/\t/);  # split on tabs
    my $keyfield=$line[2]; # values to compare are in column 3       
    if (exists($hash1{$keyfield})){
    print $filter1 $_;
    }       
}   

このスクリプトを実行すると、出力filter1.txtが空になります。列間に間違いなく一致があるため、これは正しくありません。

4

1 に答える 1

1

ブロック内で $list1 ファイルハンドルをレキシカル ( "my" ) 変数として宣言したため、そのブロック内でのみ表示されます。

したがって、スクリプトの後の行では $list1 が表示されず、前述のエラー メッセージが表示されます。

これを修正するには、ファイルを開く if.. ブロックの前に $list1 を宣言します。

スクリプトのとおり、%hash1 にキーまたは値を設定しません

あなたの仕様はあいまいですが、あなたが意図しているのは file1 から hash1 キーをロードすることです

while(<$list1>){            # $list1 is the variable from the imported .txt file
    chomp;                  # remove newlines
    my $keyfield=$_;        # this imported file contains only one column
    $hash1{$keyfield}++;    # this sets a key in %hash1
    }

次に、file2を通過するとき

while(<$file2>){                      # this is the other file with multiple columns
    my @line=split(/\t/);             # split on tabs
    my $keyfield=$line[2];            # values to compare are in column "2"      
    if (exists($hash1{$keyfield}) ){  # do hash lookup for exact match
        print $_;                     # output entire line
    } 

ちなみに、$line[2] は実際には 3 列目、最初の列は $line[0]、2 番目の列は $line[1] などです。

実際に部分一致またはパターン一致 (grep など) を実行したい場合は、ハッシュの使用は適切ではありません

print $_; # output entire line最後に、これが必要な場合は、ファイルへの出力を修正する必要があります。$filter1 への参照は、示されているスクリプト フラグメントで宣言されていないため、削除しました。

于 2013-08-12T08:11:10.343 に答える