2016-02-21 32 views
-1

我有多個輸入文件(outputXXX.pdb),我希望爲其編寫輸出文件(outputXXX.gjf)。Perl - 在具有特定擴展名的所有文件中打印標題

輸入文件具有以下格式:

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); 
} 

然而它寫入outputXXX.gjf文件不打印頭和不保留格式,更何況它打印GLOB?

GLOB(0x1622950)CAY -0.124 0.401 -0.153 
GLOB(0x1622950)HY1 -0.648 0.043 -1.064 
GLOB(0x1622950)HY2 -0.208 1.509 -0.145 

有關如何改進我的腳本的任何建議,非常感謝。

UPDATE更新後的代碼如下。這很混亂(我不是很有經驗),但可以輸出以下內容。

輸出:

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 
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); 
} 
} 
+0

行'if(/CAY/../HT2/)'的用途是什麼?你的PDB文件是否總是以相同的順序包含第三列中的三個值?文件中是否有其他行要忽略?另外,你是否希望你的輸出文件名看起來像'myfile.pdb.gjf'?這就是你所編碼的內容,但用* .gjf替換* .pdb會更平常。 – Borodin

回答

2

$header不包含標題字符串,但它的文件句柄:

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

填充$標頭的情況下文件來代替。

此外,不要在每行之前打印標題。

1

我會這樣做。我所做的主要變化是

  • use autodie而是明確檢查每個文件操作

  • 使用do塊的成功讀取gaussian.txt內容到$header

  • 替換的.pdb文件類型與.gjf而不是將其添加到末尾

  • 使用select使GJF文件的默認輸出,使print語句不需要明確的文件處理

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

  • 陣列片的使用字符串插值把空間的輸出,以避免join呼叫


#!/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"; 
    } 
} 
+0

你能幫我弄清楚這些錯誤嗎? '在串聯(。)中使用未初始化的值$ gjf_path或在./stack.pl第21行使用字符串。' 和'無法打開'/output1.gjf'寫入:'Permission denied'at ./stack.pl第21行爲什麼我會在寫權限時遇到麻煩? – EA00

+1

@ EA00:這是一個問題嗎?你沒有傳過任何參數。 – Borodin

相關問題