使用来自另一个文件的信息更改文件
Alter a file using information from another file
我想使用另一个文件中的信息更改 phylip 文件中的名称。 phylip 只是一串连续的信息,我要更改的名称(例如 aaaaaaabyd
)嵌入其中。像这样
((aaaaaaabyd:0.23400159127856412500,(((aaaaaaaaxv:0.44910864993667892753,aaaaaaaagf:0.51328033054009691849):0.06090419044604544752,((aaaaaaabyc:0.11709094683204501752,aaaaaaafzz:0.04488198976629347720):0.09529995111708353117,((aaaaaaadbn:0.34408087090010841536,aaaaaaaafj:0.47991503739434709930):0.06859184769990583908,((aaaaaaaabk:0.09244297511609228524,aaaaaaaete:0.12568841555837687030):0.28431
(没有换行)
里面的名字像aaaaaaaabk
。
另一个文件的信息更改为,与另一个文件中的信息一样,
aaaaaaaabk;Ciona savignyi
aaaaaaaete;Homo sapiens
aaaaaaaafj;Cryptosporidium hominis
aaaaaaaaad;Strongylocentrotus purpuratus
aaaaaaabyd;Theileria parva
aaaaaaaaaf;Plasmodium vivax
我已经尝试了很多东西,但这是我得到的最接近的东西。问题是它只做一个,并没有打印出 phylip 文件的其余部分。我需要去 ((Theileria parva:0.23400159127856412500 等
open(my $tree, "$ARGV[0]") or die "Failed to open file: $!\n";
open(my $csv, "$ARGV[0]") or die "Failed to open file: $!\n";
open(my $new_tree, "> raxml_tree.phy");
# Declare variables
my $find;
my $replace;
my $digest;
# put the file of the tree into string variable
my $string = <$tree>;
# open csv file
while (my $line = <$csv>) {
# aaaaaaaaaa;Ciona savignyi
if ($line =~ m/(\w+)\;+(\w+\s+\w*)/) {
$find = ;
$replace = ;
$string =~ s/$find/$replace/g;
}
}
print $new_tree "$string";
close $tree;
close $csv;
close $new_tree;
关于您自己的代码的一些指南
问题几乎可以肯定是您打开同一个文件 $ARGV[0]
两次。大概一个应该是`$ARGV[1]
你必须总是use strict
和use warnings
在每个Perl的顶部您编写的程序(除非 use strict
到位,否则声明变量几乎没有意义)并使用 my
声明所有变量,尽可能接近它们的第一个使用点。一开始就在一个块中声明所有变量是一种不好的形式,因为它使它们都有效地成为全局变量,并且您失去了声明词法变量的大部分优势
你应该使用open
的三参数形式,最好将文件名放在die
字符串中,这样你就可以看看哪个失败了。所以
open(my $tree, "$ARGV[0]") or die "Failed to open file: $!\n";
变成
open my $tree, '<', $ARGV[0] or die qq{Failed to open "$ARGV[0]" for input: $!\n};
您应该寻找更简单的解决方案,而不是每次都应用正则表达式方法。 $line =~ m/(\w+)\;+(\w+\s+\w*)/
比 chomp
、split /;/
简洁得多
当你只需要变量的值时,你不应该在变量周围使用双引号,所以 print $new_tree "$string"
应该是 print $new_tree $string
而不是尝试使用 其他文件 中的数据(请尝试为您的问题中的项目使用有用的名称,因为在编写时很难知道如何称呼它们一个解决方案)最好构建一个包含所有翻译的散列
这个程序会按照你的要求去做。它构建了一个由所有哈希键的交替组成的正则表达式,然后将该模式的所有出现转换为其对应的名称。仅翻译样本 其他文件 中的名称:其他保留原样
use strict;
use warnings;
use 5.014; # For non-destructive substitution
use autodie;
my %names;
open my $fh, '<', 'other_file.txt';
while ( <$fh> ) {
my ($k, $v) = split /;/, s/\s+\z//r;
$names{$k} = $v;
}
open $fh, '<', 'phylip.txt';
my $data = <$fh>;
close $fh;
my $re = join '|', sort { length $b <=> length $a } keys %names;
$re = qr/(?:$re)/;
$data =~ s/\b($re)\b/$names{}/g;
print $data;
输出
((Theileria parva:0.23400159127856412500,(((aaaaaaaaxv:0.44910864993667892753,aaaaaaaagf:0.51328033054009691849):0.06090419044604544752,((aaaaaaabyc:0.11709094683204501752,aaaaaaafzz:0.04488198976629347720):0.09529995111708353117,((aaaaaaadbn:0.34408087090010841536,Cryptosporidium hominis:0.47991503739434709930):0.06859184769990583908,((Ciona savignyi:0.09244297511609228524,Homo sapiens:0.12568841555837687030):0.28431
更新
这是您自己的程序的修订版,考虑了以上几点并修复了错误
use strict;
use warnings;
open my $tree_fh, '<', $ARGV[0] or die qq{Failed to open "$ARGV[0]" for input: $!\n};
my $string = <$tree_fh>;
close $tree_fh;
open my $csv_fh, '<', $ARGV[1] or die qq{Failed to open "$ARGV[1]" for input: $!\n};
while ( <$csv_fh> ) {
chomp;
my ($find, $replace) = split /;/;
$string =~ s/$find/$replace/g;
}
close $csv_fh;
open my $new_tree_fh, '>', 'raxml_tree.phy' or die qq{Failed to open "raxml_tree.phy" for output: $!\n};
print $new_tree_fh $string;
close $new_tree_fh;
我想使用另一个文件中的信息更改 phylip 文件中的名称。 phylip 只是一串连续的信息,我要更改的名称(例如 aaaaaaabyd
)嵌入其中。像这样
((aaaaaaabyd:0.23400159127856412500,(((aaaaaaaaxv:0.44910864993667892753,aaaaaaaagf:0.51328033054009691849):0.06090419044604544752,((aaaaaaabyc:0.11709094683204501752,aaaaaaafzz:0.04488198976629347720):0.09529995111708353117,((aaaaaaadbn:0.34408087090010841536,aaaaaaaafj:0.47991503739434709930):0.06859184769990583908,((aaaaaaaabk:0.09244297511609228524,aaaaaaaete:0.12568841555837687030):0.28431
(没有换行)
里面的名字像aaaaaaaabk
。
另一个文件的信息更改为,与另一个文件中的信息一样,
aaaaaaaabk;Ciona savignyi
aaaaaaaete;Homo sapiens
aaaaaaaafj;Cryptosporidium hominis
aaaaaaaaad;Strongylocentrotus purpuratus
aaaaaaabyd;Theileria parva
aaaaaaaaaf;Plasmodium vivax
我已经尝试了很多东西,但这是我得到的最接近的东西。问题是它只做一个,并没有打印出 phylip 文件的其余部分。我需要去 ((Theileria parva:0.23400159127856412500 等
open(my $tree, "$ARGV[0]") or die "Failed to open file: $!\n";
open(my $csv, "$ARGV[0]") or die "Failed to open file: $!\n";
open(my $new_tree, "> raxml_tree.phy");
# Declare variables
my $find;
my $replace;
my $digest;
# put the file of the tree into string variable
my $string = <$tree>;
# open csv file
while (my $line = <$csv>) {
# aaaaaaaaaa;Ciona savignyi
if ($line =~ m/(\w+)\;+(\w+\s+\w*)/) {
$find = ;
$replace = ;
$string =~ s/$find/$replace/g;
}
}
print $new_tree "$string";
close $tree;
close $csv;
close $new_tree;
关于您自己的代码的一些指南
问题几乎可以肯定是您打开同一个文件
$ARGV[0]
两次。大概一个应该是`$ARGV[1]你必须总是
use strict
和use warnings
在每个Perl的顶部您编写的程序(除非use strict
到位,否则声明变量几乎没有意义)并使用my
声明所有变量,尽可能接近它们的第一个使用点。一开始就在一个块中声明所有变量是一种不好的形式,因为它使它们都有效地成为全局变量,并且您失去了声明词法变量的大部分优势你应该使用
open
的三参数形式,最好将文件名放在die
字符串中,这样你就可以看看哪个失败了。所以open(my $tree, "$ARGV[0]") or die "Failed to open file: $!\n";
变成
open my $tree, '<', $ARGV[0] or die qq{Failed to open "$ARGV[0]" for input: $!\n};
您应该寻找更简单的解决方案,而不是每次都应用正则表达式方法。
$line =~ m/(\w+)\;+(\w+\s+\w*)/
比chomp
、split /;/
简洁得多
当你只需要变量的值时,你不应该在变量周围使用双引号,所以
print $new_tree "$string"
应该是print $new_tree $string
而不是尝试使用 其他文件 中的数据(请尝试为您的问题中的项目使用有用的名称,因为在编写时很难知道如何称呼它们一个解决方案)最好构建一个包含所有翻译的散列
这个程序会按照你的要求去做。它构建了一个由所有哈希键的交替组成的正则表达式,然后将该模式的所有出现转换为其对应的名称。仅翻译样本 其他文件 中的名称:其他保留原样
use strict;
use warnings;
use 5.014; # For non-destructive substitution
use autodie;
my %names;
open my $fh, '<', 'other_file.txt';
while ( <$fh> ) {
my ($k, $v) = split /;/, s/\s+\z//r;
$names{$k} = $v;
}
open $fh, '<', 'phylip.txt';
my $data = <$fh>;
close $fh;
my $re = join '|', sort { length $b <=> length $a } keys %names;
$re = qr/(?:$re)/;
$data =~ s/\b($re)\b/$names{}/g;
print $data;
输出
((Theileria parva:0.23400159127856412500,(((aaaaaaaaxv:0.44910864993667892753,aaaaaaaagf:0.51328033054009691849):0.06090419044604544752,((aaaaaaabyc:0.11709094683204501752,aaaaaaafzz:0.04488198976629347720):0.09529995111708353117,((aaaaaaadbn:0.34408087090010841536,Cryptosporidium hominis:0.47991503739434709930):0.06859184769990583908,((Ciona savignyi:0.09244297511609228524,Homo sapiens:0.12568841555837687030):0.28431
更新
这是您自己的程序的修订版,考虑了以上几点并修复了错误
use strict;
use warnings;
open my $tree_fh, '<', $ARGV[0] or die qq{Failed to open "$ARGV[0]" for input: $!\n};
my $string = <$tree_fh>;
close $tree_fh;
open my $csv_fh, '<', $ARGV[1] or die qq{Failed to open "$ARGV[1]" for input: $!\n};
while ( <$csv_fh> ) {
chomp;
my ($find, $replace) = split /;/;
$string =~ s/$find/$replace/g;
}
close $csv_fh;
open my $new_tree_fh, '>', 'raxml_tree.phy' or die qq{Failed to open "raxml_tree.phy" for output: $!\n};
print $new_tree_fh $string;
close $new_tree_fh;