【问题标题】:file column comparison and appending output in perlperl 中的文件列比较和附加输出
【发布时间】:2017-04-22 20:04:19
【问题描述】:

我的两个输入文件为:

file1.txt 为,

NP_418770.2
NP_416485.4

和file2.txt一样,

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

(请注意,我将file2、3和4输出中的“,”更改为“;”,因此不会干扰csv文件的格式)

虽然我在初步案例中尝试使用 awk,但如何使用 perl 代码来完成?

【问题讨论】:

  • 为什么需要切换到 Perl?

标签: perl


【解决方案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} };
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多