Perl-打印具有特定扩展名的所有文件中的头文件

Perl-打印具有特定扩展名的所有文件中的头文件,perl,Perl,我有多个输入文件(outputXXX.pdb),我想为其编写输出文件(outputXXX.gjf) 输入文件的格式如下: ATOM 1 CAY GLY X 1 -0.124 0.401 -0.153 1.00 2.67 PEP ATOM 2 HY1 GLY X 1 -0.648 0.043 -1.064 1.00 0.00 PEP ATOM 3 HY2 GLY X 1 -0.20

我有多个输入文件(outputXXX.pdb),我想为其编写输出文件(outputXXX.gjf)

输入文件的格式如下:

ATOM      1  CAY GLY X   1      -0.124   0.401  -0.153  1.00  2.67      PEP
ATOM      2  HY1 GLY X   1      -0.648   0.043  -1.064  1.00  0.00      PEP
ATOM      3  HY2 GLY X   1      -0.208   1.509  -0.145  1.00  0.00      PEP
对于每个输入文件,我想创建一个输出文件,其中包含一个单独的文本文件“gaussian.txt”中的标题,并获取每个相应输入文件的第2、6、7、8列中的内容,生成如下内容:

Title
Header Line 1
Header Line 2

CAY   -0.124   0.401  -0.153
HY1   -0.648   0.043  -1.064  
HY2   -0.208   1.509  -0.145
下面是我当前的脚本

#!/usr/bin/perl

use strict;
use warnings;

use File::Basename;

my $input_path  = $ARGV[0];
my $output_path = $ARGV[1];

foreach my $filename (<$input_path/*.pdb>) {

    my $output_file = basename( $filename, '.pdb' );

    open( my $input_fh,  "<", $filename )                       or die $!;
    open( my $output_fh, ">", "$output_path/$output_file.gjf" ) or die $!;
    open( my $header,    "<", "gaussian.txt" )                  or die $!;

    while (<$input_fh>) {
        if ( /CAY/ .. /HT2/ ) {
            print {$output_fh} $header;
            print {$output_fh} join( " ", +(split)[ 2, 6, 7, 8 ] ), "\n";
        }
    }

    close($output_fh);
    close($input_fh);
}
任何关于如何改进我的脚本的建议都将不胜感激

更新更新了下面的代码。它很混乱(我不是很有经验),但支持以下输出

输出:

 Title
 Header Line 1
 Header Line 2

 CAY-0.124 0.401 -0.153
 HY1-0.648 0.043 -1.064
 HY20.208 1.509 -0.145
代码:

#/usr/bin/perl
严格使用;
使用警告;
使用File::Basename;
我的$input_path=$ARGV[0];
我的$output_path=$ARGV[1];
my$header=“gaussian.txt”;
foreach my$filename(){
我的$output_file=basename($filename,.pdb');
打开(my$header\u fh,“,”$output\u path/$output\u file.gjf”)或die$!;
打印{$output_fh}@行;

open(my$input_fh,“
$header
不包含头字符串,但其文件句柄:

open (my $header, "<", "gaussian.txt") or die $!;

open(my$header),我会这样做。我所做的主要更改是

  • 使用autodie
    而不是显式检查每个文件操作的成功与否

  • 使用
    do
    块将
    gaussian.txt
    的内容读入
    $header

  • .pdb
    文件类型替换为
    .gjf
    ,而不是将其添加到末尾

  • 使用
    select
    使GJF文件成为默认输出,以便
    print
    语句不需要显式的文件句柄

  • 使用
    next/\S/
    处理包含非空格字符的每一行输入文件

  • 使用数组切片的字符串插值在输出中放入空格,以避免调用
    join


!/usr/bin/perl
严格使用;
使用警告;
使用v5.10.1;
使用自动模具;
使用文件::Basename“Basename”;
my($pdb_路径,$gjf_路径)=@ARGV;
我的$header=do{
打开我的$fh,,“$gjf_路径/$gjf_文件”;
选择$gjf_fh;
打印$header;

打开我的$pdb_fh,'如果(/CAY/./HT2/),行
if的用途是什么
?您的PDB文件是否总是在第三列中以相同的顺序精确地包含这三个值?文件中是否还有其他行需要忽略?此外,您是否希望输出文件名看起来像
myfile.PDB.gjf
?这就是您所编码的,但更常见的做法是将
.PDB
替换为de>.gjf
您能帮我找出这些错误吗?
在串联(.)中使用未初始化值$gjf\u path或者./stack.pl第21行的字符串。
无法打开“/output1.gjf”进行写入。./stack.pl第21行的“权限被拒绝”
为什么写入权限会有问题?@EA00:这是个问题吗?您没有传递任何参数。
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;

my $input_path = $ARGV[0];
my $output_path = $ARGV[1];
my $header = "gaussian.txt";

foreach my $filename (<$input_path/*.pdb>) {
        my $output_file = basename ( $filename, '.pdb');
    open (my $header_fh, "<", $header) or die $!;
        my @lines;
        while (<$header_fh>) {
        push (@lines, $_);
    open (my $output_fh, ">", "$output_path/$output_file.gjf") or die $!;
        print {$output_fh} @lines;
    open (my $input_fh, "<", $filename) or die $!;
        while ( <$input_fh>) {
        if (/CAY/../HT2/) {
                print {$output_fh} join (" ", (split)[2,6,7,8]), "\n";
                }
                }
        close($output_fh);
        close($input_fh);
}
}
open (my $header, "<", "gaussian.txt") or die $!;
#!/usr/bin/perl

use strict;
use warnings;
use v5.10.1;
use autodie;

use File::Basename 'basename';

my ( $pdb_path, $gjf_path ) = @ARGV;

my $header = do {
    open my $fh, '<', 'gaussian.txt';
    local $/;
    <$fh>;
};

for my $pdb_file ( glob "$pdb_path/*.pdb" ) {

    ( my $gjf_file = basename($pdb_file) ) =~ s/\.pdb$/.gjf/;

    open my $gjf_fh, '>', "$gjf_path/$gjf_file";
    select $gjf_fh;

    print $header;

    open my $pdb_fh, '<', $pdb_file;

    while ( <$pdb_fh> ) {
        next unless /\S/;
        my @fields = split;
        print "@fields[2,6,7,8]\n";
    }
}