如何在 perl 上正确指定这些变量?
How do I specify these variables correctly on perl?
我 运行 一个分子动力学模拟,它给了我 2,000 个轨迹文件。这些文件的文件名格式为 au25-c2-benzalacetone.001
,最大为 2000。我编写了一个通用的 perl 程序,但它没有读取 2,000 个文件。我如何修改我的代码,以便它读取每个文件并分别提取我想要的每个文件的坐标?我需要 2,000 coordinates_of_interest.dat
个文件。这里的 tinker 文件是 au25-c2-benzalacetone
文件。这是我写的代码:
#!/usr/bin/env perl
use Math::VectorReal;
use Math::Trig qw/acos/;
use strict;
use warnings;
my $file1 = $ARGV[0];
my $n1 = $ARGV[1];
my $n2 = $ARGV[2];
my $tinker_file = sprintf "%s.%03d"
my( $file1, $n1, $n2 ) = @ARGV;
foreach $tinker_file (glob "$tinker_file.*") {
print "Filename: $tinker_file\n";
}
my $file2 = "coordinates_of_interest.dat";
my %lines_of_interest = map { $_ => 1 } 18, 25, 26;
{
open(FILE2, '>', $file2) or die "couldn't open the file!";
for(my $i=$n1;$i<=$n2;$i++){
{
open(FILE1, '<', $tinker_file) or die "couldn't open the file!";
{
my $num_lines = keys %lines_of_interest;
while (<FILE1>) {
if ($lines_of_interest{$.}) {
print FILE2;
last unless --$num_lines;
}
}
}
}
}
}
~
~
~
如果文件格式是 au25-c2-benzalacetone.001
,您的第一个问题似乎是 $i
可能不是三位数。你可能想要my $tinker_file = sprintf "%s.%03d", $file1, $i;
我注意到的另一个问题是您一直打开 "coordinates_of_interest.dat" 进行写入,而不是追加,因此只有最后一个文件才会有它的三行。我建议,如果您要为所有输入写入单个文件,请在 for
循环的 外部 (之前)打开该文件,并在循环结束后关闭它完成。
glob
是您的朋友,请使用通配符并搜索目录:
my ( $filespec, $n1, $n2 ) = @ARGV;
foreach my $file ( glob "$filespec.*" ) {
print "Filename: $file\n";
}
或者您可以使用 glob
扩展模式:
my $expr = join ",", 0..9;
foreach my $entry ( glob ( "test.{$expr}{$expr}{$expr}" ) ) {
print $entry,"\n";
}
但我可能会坚持第一个,因为这将确保文件确实存在。
These files have the file name format au25-c2-benzalacetone.001 up to 2000.
my $tinker_file = sprintf "%s.%03d"
除了这一行不完整之外,您不能在三位数字段中输入 1 到 2000 之间的数字。这可能就是您的脚本没有读取所有文件的原因。
我 运行 一个分子动力学模拟,它给了我 2,000 个轨迹文件。这些文件的文件名格式为 au25-c2-benzalacetone.001
,最大为 2000。我编写了一个通用的 perl 程序,但它没有读取 2,000 个文件。我如何修改我的代码,以便它读取每个文件并分别提取我想要的每个文件的坐标?我需要 2,000 coordinates_of_interest.dat
个文件。这里的 tinker 文件是 au25-c2-benzalacetone
文件。这是我写的代码:
#!/usr/bin/env perl
use Math::VectorReal;
use Math::Trig qw/acos/;
use strict;
use warnings;
my $file1 = $ARGV[0];
my $n1 = $ARGV[1];
my $n2 = $ARGV[2];
my $tinker_file = sprintf "%s.%03d"
my( $file1, $n1, $n2 ) = @ARGV;
foreach $tinker_file (glob "$tinker_file.*") {
print "Filename: $tinker_file\n";
}
my $file2 = "coordinates_of_interest.dat";
my %lines_of_interest = map { $_ => 1 } 18, 25, 26;
{
open(FILE2, '>', $file2) or die "couldn't open the file!";
for(my $i=$n1;$i<=$n2;$i++){
{
open(FILE1, '<', $tinker_file) or die "couldn't open the file!";
{
my $num_lines = keys %lines_of_interest;
while (<FILE1>) {
if ($lines_of_interest{$.}) {
print FILE2;
last unless --$num_lines;
}
}
}
}
}
}
~
~
~
如果文件格式是 au25-c2-benzalacetone.001
,您的第一个问题似乎是 $i
可能不是三位数。你可能想要my $tinker_file = sprintf "%s.%03d", $file1, $i;
我注意到的另一个问题是您一直打开 "coordinates_of_interest.dat" 进行写入,而不是追加,因此只有最后一个文件才会有它的三行。我建议,如果您要为所有输入写入单个文件,请在 for
循环的 外部 (之前)打开该文件,并在循环结束后关闭它完成。
glob
是您的朋友,请使用通配符并搜索目录:
my ( $filespec, $n1, $n2 ) = @ARGV;
foreach my $file ( glob "$filespec.*" ) {
print "Filename: $file\n";
}
或者您可以使用 glob
扩展模式:
my $expr = join ",", 0..9;
foreach my $entry ( glob ( "test.{$expr}{$expr}{$expr}" ) ) {
print $entry,"\n";
}
但我可能会坚持第一个,因为这将确保文件确实存在。
These files have the file name format au25-c2-benzalacetone.001 up to 2000.
my $tinker_file = sprintf "%s.%03d"
除了这一行不完整之外,您不能在三位数字段中输入 1 到 2000 之间的数字。这可能就是您的脚本没有读取所有文件的原因。