perl

时间:2016-12-07 18:39:25

标签: perl

用我的两个输入文件:

file1.txt as,

NP_418770.2
NP_416485.4

和file2.txt as,

NP_415931.4: 1-8, 29-40, 69-80, 100-111, 124-132
NP_418770.2: 264-293
YP_026226.4: 84-101, 174-182, 208-217, 332-341, 376-388, 593-606
NP_416485.4: 1-18, 16-25, 106-122, 129-153
NP_417679.2: 1-10
NP_417044.4: 1-25, 221-231, 825-836

只获取file2中file1的匹配第一列值并将输出文件写为(output.txt):

NP_418770.2: 264-293
NP_416485.4: 1-18, 16-25, 106-122, 129-153

我使用awk代码:

awk -F: "FNR==NR {a[$1]=$0; next}; $1 in a {print a[$1]}" file2.txt file1.txt > output.txt

现在,在更新的情况下,除了上面的输入之外,我还有两个输入文件具有相同格式的file2.txt:

file3.txt

NP_415931.4: 11-88, 59-90, 119-130
NP_418770.2: 254-283

和file4.txt

NP_418770.2: 24-29, 33-50
NP_416485.4: 1-8, 16-22, 26-32, 39-53

我已经有一个csv格式的output.csv文件(带标题):

RefSeq_ID,a,b,c,d,e,f,Go_terms(%)
NP_418770.2,25,83,0,0,0,0,GO:0005887
NP_416485.4,13,19,8,12,0,0,GO:0016878 GO:0051108

现在,我的问题是,如何在预先存在的output.csv中附加所有三个输入文件的输出?我想要的上述情况的修改样本output.csv将是(第一行是标题):

RefSeq_ID,file2_output,file3_output,file4_output,a,b,c,d,e,f,Go_terms
NP_418770.2,264-293,254-283,24-29; 33-50,25,83,0,0,0,0,GO:0005887
NP_416485.4,1-18; 16-25; 106-122; 129-153,,1-8; 16-22; 26-32; 39-53,13,19,8,12,0,0,GO:0016878 GO:0051108

(请注意,我将","在文件2,3和4输出中更改为&#34 ;;"因此不会干扰csv文件的格式)

虽然我尝试使用awk作为初步案例,如何使用perl代码完成?

1 个答案:

答案 0 :(得分:1)

这几乎产生了你想要的输出,只是线的顺序并不总是保留。

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

open my $F1, '<', 'file1.txt' or die $!;
my %f1;
while (<$F1>) {
    chomp;
    $f1{$_} = 1;
}

my %output;
my $count = 1;
for my $file (qw( file2.txt file3.txt file4.txt )) {
    open my $F2, '<', $file or die $!;
    while (<$F2>) {
        chomp;
        my @cells = split qr/[,:] /;
        push @{ $output{ $cells[0] } }, [ @cells[ 1 .. $#cells ] ]
            if exists $f1{ $cells[0] };
    }
    @$_ != $count and push @$_, [] for values %output;
    ++$count;
}
open my $F2, '<', 'output.csv' or die $!;
while (<$F2>) {
    chomp;
    my ($key, $rest) = split /,/, $_, 2;
    push @{ $output{$key} }, [$rest] if exists $f1{$key};
}


for my $k (keys %output) {
    say "$k,", join ',', map { join '; ', @$_ } @{ $output{$k} };
}

它创建了由第一列键入的数组的哈希值,来自不同文件的值被推送到循环中的内部数组中,空数组被推送到缺少的键以获得双逗号。