Perl:如何联接文本文件的两列,其中第一列的值应与第二列的值顺序匹配

时间:2019-07-17 12:59:34

标签: perl bioinformatics

我是Perl编程的初学者。我现在正在研究的问题是如何从文本文件中获取基因长度。文本文件包含基因名称(第10列),起始位点(第6列),结束位点(第7列)。长度可以从第6列和第7列的差异中得出。但是我的问题是如何将基因名称(来自第10列)与从第6列和第7列的差异中得出的相应差异进行匹配。非常感谢! / p>

open (IN, "Alu.txt");
open (OUT, ">Alu_subfamlength3.csv");

while ($a = <IN>) {
    @data = split (/\t/, $a);
    $list {$data[10]}++;
    $genelength {$data[7] - $data[6]};
}

foreach $sub (keys %list){
    $gene = join ($sub, $genelength);

    print "$gene\n";
}
close (IN);
close (OUT);

2 个答案:

答案 0 :(得分:2)

我不确定,因为我没有看到您的数据。但我认为您正在为此付出不必要的努力。我认为每个基因所需的一切都在输入文件的一行中,因此您可以一次处理一行文件,而无需使用任何额外的变量。像这样:

open (IN, "Alu.txt");
open (OUT, ">Alu_subfamlength3.csv");

while ($a = <IN>) {
    @data = split (/\t/, $a);
    print "Gene: $data[10] / Length: ", $data[7] - $data[6], "\n";
}

但是我们可以做一些改进。首先,我们将停止使用$a(这是一个特殊变量,不应在随机代码中使用),而改用$_。同时,我们将添加use strictuse warnings,并确保声明了我们所有的变量。

use strict;
use warnings;

open (IN, "Alu.txt");
open (OUT, ">Alu_subfamlength3.csv");

while (<IN>) { # This puts the line into $_
    my @data = split (/\t/); # split uses $_ by default
    print OUT "Gene: $data[10] / Length: ", $data[7] - $data[6], "\n";
}

接下来,我们将删除split()调用中不必要的括号,并使用列表切片仅获取所需的值并将其存储在各个变量中。

use strict;
use warnings;

open (IN, "Alu.txt");
open (OUT, ">Alu_subfamlength3.csv");

while (<IN>) { # This puts the line into $_
    my ($start, $end, $gene) = (split /\t/)[6, 7, 10]; # split uses $_ by default
    print OUT "Gene: $gene / Length: ", $end - $start, "\n";
}

接下来,我们将删除显式文件名。相反,我们将从STDIN中读取数据并将其写入STDOUT。这是一种常见的Unix / Linux方法,称为 I / O过滤器。它将使您的程序更加灵活(此外,更容易编写)。

use strict;
use warnings;

while (<>) { # Empty <> reads from STDIN
    my ($start, $end, $gene) = (split /\t/)[6, 7, 10];
    # print to STDOUT
    print "Gene: $gene / Length: ", $end - $start, "\n";
}

要使用此程序,我们使用称为 I / O重定向的操作系统功能。如果程序名为filter_genes,我们将这样称呼它:

$ ./filter_genes < Alu.txt > Alu_subfamlength3.csv

如果将来文件名更改,则无需更改程序,只需更改调用它的命令行即可。

答案 1 :(得分:0)

我假设您的输入数据以制表符分隔,并且您想要一个包含基因名称及其对应基因长度的输出csv文件

预期产量

genename1,12
genename2,20
genename3,8

下面是我根据这些假设编写的代码

use strict;
use warnings;

my $input_file;
my $output_file;

my %hash_gene;

open ($input_file,  "<testdata.txt") or die "Can not open file [$input_file]";
open ($output_file, ">outdata.txt")  or die "Can not open file [$output_file]";

while (<$input_file>) {
    chomp;
    my @data = split (/\t/, $_);

    $hash_gene{$data[10]} = $data[7] - $data[6];
}

foreach my $sub (keys %hash_gene){
    print $output_file "$sub,$hash_gene{$sub}\n";
}   
close ($input_file);
close ($output_file);

注释

  • 我修改了文件名,并根据需要更改了
  • 数组索引基于0,假设您提到列号(例如,第一列为列0)