Perl 在两个文件之间匹配值(多个if函数)并粘贴值
我有两个包含多列的txt文件。这是第一个文件(Perl 在两个文件之间匹配值(多个if函数)并粘贴值,perl,Perl,我有两个包含多列的txt文件。这是第一个文件($frequency)的外观: C1 C2 A a B b C c D d text 1 0 1 0 0 0 0 0 0 text 2 1 0 5 4 0 0 0 0 text 3 0 0 0 0 10 11 3 6 text 4 1 0 9 4 0 2 0 0 text
$frequency
)的外观:
C1 C2 A a B b C c D d
text 1 0 1 0 0 0 0 0 0
text 2 1 0 5 4 0 0 0 0
text 3 0 0 0 0 10 11 3 6
text 4 1 0 9 4 0 2 0 0
text 5 5 3 0 0 6 7 4 0
因此C2包含从1到20000的所有位置。列A-d包含的数值都等于或大于0
这是第二个文件($variants
)的外观
C1 C2 C3 C4
text 2 A D
text 4 B C
text 5 A B,D
C2在这里包含一些介于1和20000之间的值。C3和C4包含A-D之间的字母(与表1中的列名类似,但都是大写字母)。我现在想做的是:将$variants
中C2中的值与$frequency
中C2中的值进行匹配,然后检查$variants
中C3中的哪个字母,然后复制相应的值(因此,请使用大写和小写字母更正行和列)从$frequency
到$variants
中的两个新列。然后需要对$variants
的C4执行相同的操作
编辑:有时,$variants
中的C4也可能包含两个字母,用“,”分隔。对于这两个字母,$frequency
中的值应显示在输出中
根据这个例子,输出应该是这样的
C1 C2 C3 C4 C5 C6 C7 C8 C9 C10
text 2 A D 1 0 0 0 empty
text 4 B C 9 4 0 2 empty
text 5 A B,D 5 3 0 0 4 0
我已经从脚本开始了,但是我被困在了需要比较值和字母的地方
这就是我到目前为止所做的:
my $table1 = prompt("Give the name of the file with variants:\n");
open(my $variants, '<',$table1) || die "Could not open file $table1 $!";
my $table2 = prompt("Give the name of the file with the frequencies: \n");
open(my $frequency, '<',$table2) || die "Could not open file $table2 $!";
my (@position, @A, @a, @B, @b, @C, @c, @D, @d); #instead of using hashes I was trying to put all the values in arrays, because I don't know how to hash multiple columns from a file.
while(<$frequency>){
my @column = split(/\t/); # split on tabs
$position[$_] .= "$column[1] "; # I want to assign the correct column values to the arrays
$Afor[$_] .= "$column[2] ";
$arev[$_] .= "$column[3] ";
$Bfor[$_] .= "$column[4] ";
$brev[$_] .= "$column[5] ";
$Cfor[$_] .= "$column[6] ";
$crev[$_] .= "$column[7] ";
$Dfor[$_] .= "$column[8] ";
$drev[$_] .= "$column[9] ";
}
while(<$variants>){
next if /^\s*#/; # skipping some lines
next if /^\s*"/;
chomp;
my ($chr, $pos, $refall, $altall) = split;
}
my$table1=prompt(“给出带有变量的文件名:\n”);
打开(my$variants),最重要的第一步通常是选择正确的数据结构来保存数据。我认为频率文件内容最简单的结构就是哈希数组。如下所示:
use strict; use warnings;
use English '-no_match_vars';
my ($variants_file, $frequency_file) = @ARGV; # take filename from command line
open my $variants, '<', $variants_file or die "Could not open file $variants_file: $!";
open my $frequency, '<', $frequency_file or die "Could not open file $frequency_file $!";
# parse the header fields
my (undef, undef, @header) = do {
my $header_line = <$frequency>;
chomp $header_line;
split /\t/, $header_line;
};
my @frequency_data;
my $expect_pos = 1; # starting position
while (<$frequency>){
chomp;
my(undef, $pos, @column) = split /\t/; # split on tabs
unless ($pos == $expect_pos) {
die "On line $INPUT_LINE_NUMBER: expected data for position $expect_pos, instead found position $pos";
}
@{ $frequency_data[$pos] }{@header} = @column;
++$expect_pos;
}
我希望这会有所帮助。最重要的第一步通常是选择正确的数据结构来保存数据。我认为频率文件内容最简单的结构就是哈希数组。如下所示:
use strict; use warnings;
use English '-no_match_vars';
my ($variants_file, $frequency_file) = @ARGV; # take filename from command line
open my $variants, '<', $variants_file or die "Could not open file $variants_file: $!";
open my $frequency, '<', $frequency_file or die "Could not open file $frequency_file $!";
# parse the header fields
my (undef, undef, @header) = do {
my $header_line = <$frequency>;
chomp $header_line;
split /\t/, $header_line;
};
my @frequency_data;
my $expect_pos = 1; # starting position
while (<$frequency>){
chomp;
my(undef, $pos, @column) = split /\t/; # split on tabs
unless ($pos == $expect_pos) {
die "On line $INPUT_LINE_NUMBER: expected data for position $expect_pos, instead found position $pos";
}
@{ $frequency_data[$pos] }{@header} = @column;
++$expect_pos;
}
我希望这会有所帮助。您试图解释如何创建输出,但如果您可以发布一个包含输入文件和预期输出的完整示例,以便我们测试我们的解决方案,那就容易多了。@amon我更改了输入和输出示例以更好地反映现实您试图解释如何创建输出,但如果您可以发布一个包含输入文件和预期输出的完整示例,这样我们就可以测试我们的解决方案,那就容易多了。@amon I更改了输入和输出示例,以更好地反映现实大量语法错误,并要求提供几乎所有的显式包名@
@kdkeck使用英语”的含义是什么-匹配变量“
?@kdkeck,为什么您现在使用$expect\u pos
和$pos
而不是$position
?@user1987607英语
模块为所谓的标点符号变量提供长名称。
是行号,但英语为该变量提供了$INPUT\u line\u number
-导入英语时,无匹配变量
选项可避免所有正则表达式匹配的运行时惩罚(由于不幸的设计事故,这是必要的)。我将名称更改为$expect_pos
,因为它更好地表达了该变量的含义:这是我们期望的位置。@user1987607是的,这是一个额外的拆分–我在映射
表达式中进行了拆分。有很多语法错误,几乎所有@
@kdkeck都要求显式的包名。这是什么意思使用英语“不匹配变量”
?@kdkeck,为什么现在使用$expect\u pos
和$pos
而不是$position
?@user1987607英语
模块为所谓的标点符号变量提供了长名称。$
是行号,但英语提供了$INPUT\u行号
r该变量。-no_match_vars
选项在导入英语时避免了对所有正则表达式匹配的运行时惩罚(由于不幸的设计事故而必需)。我将名称更改为$expect\u pos
,因为它更好地表达了该变量的含义:这是我们在那里期望的位置。@user1987607是的,这是一个额外的拆分–我在映射
表达式中进行了拆分。
<$variants>;
while (<$variants>) {
next if ...
chomp;
my ($text, $pos, @cols) = split /\t/;
my @data = map {@{ $frequency_data[$pos] }{$_, lc $_}} # column to values
map { split /,/ } @cols; # split cols at comma
print join("\n", $text, $pos, @cols, @data), "\n";
}