2017-07-27 196 views
2

下面是我的輸入文件以及我的輸出文件。需要幫助來讀取和寫入輸入文件。 (PS:輸入和輸出是同一個文件)PERL:在輸入文件中寫入(不覆蓋原始文件)

TS_dunit_  PDX_VER_6 
TS_test1_par PDX_VER_0 

我的代碼看起來像下面;

#!/usr/perl/5.14.1 

use Getopt::Long; 
use strict; 
use warnings; 

my $file; 

GetOptions(
    "iofile=s" => \$file 
    ); 
if (not defined $file){ 
print "Please specify input_output (iofile) file\n"; 
exit; 
} 

open (my $fh, "$file") or die "Can't open the file $file: "; 
open (my $fh1, ">>$file") or die "Can't open the file $file: "; 

while (<$fh>){ 
chomp $_; 
next if ($_ !~ /S+/); 
$_ =~ /(\S+)\s+(\S+)/; 
my $first_underscore =index ($1, '_'); 
my $dev = substr ($1, $first_underscore + 1, 
     rindex ($1, '_') - $first_underscore - 1); 
my $tag = $2; 
my $cat_path = "/testdata/17.26.6/$dev/sd/$tag"; 
my $arc_path = "archive/$dev/sd/$tag"; 
if (-d $cat_path){ 
      print $fh1 "$dev $tag IN_CAD\n"; 
    }elsif (-d $arc_path){ 
      print $fh1 "$dev $tag IN_ARCHIVE\n"; 
    }else{ 
      print $fh1 "NA\n"; 
    } 

} 
    print "Done! File been append.\n"; 

以上代碼給出的

TS_dunit_   PDX_VER_6  
    TS_test1_par  PDX_VER_0   


    IN_CAD 
    IN_CAD 

輸出需要幫助,如果反正我可以使輸出如下代替。

TS_dunit_   PDX_VER_6  IN_CAD 
    TS_test1_par  PDX_VER_0  IN_CAD 
+0

文件_無法更改,以便添加到其行而不覆蓋它。無關緊要:您根據需要編寫輸出文件(附加行),然後將其重命名爲原始文件。最後,根據需要更改原始文件。 (在一個簡單的方法中,inode號碼將會改變,你是否在意這一點?) – zdim

+0

非常感謝。真的很看重你的建議,我現在編碼... –

回答

1

無法覆蓋文件的其餘部分,無法追加到文件中的一行。一個文件是一個字節序列,我們不能「插入」新的文件,只能覆蓋現有的文件(或者通過擴展文件來添加更多的文件)。例如,請參閱this post瞭解更多詳情。

而是寫出一個新文件,然後將其重命名爲原始文件。這確實改變了inode號碼;如果你需要保持它看到最後。該代碼通過正則表達式簡化了index + substr部分。

use warnings; 
use strict; 
use feature 'say'; 
use File::Copy qw(mv); 

# ... code from the question 

open my $fh,  '<', $file or die "Can't open $file:$!"; 
open my $fh_out, '>', $outfile or die "Can't open $outfile:$!"; 

while (<$fh>) 
{ 
    next if not /\S/; 
    chomp; 

    my ($dev, $tag) = /.*?_(.*)_\s+(.*)/; 

    my $cat_path = "/testdata/17.26.6/$dev/sd/$tag"; 
    my $arc_path = "archive/$dev/sd/$tag"; 

    if (-d $cat_path) { 
     say $fh_out "$_ IN_CAD"; 
    } 
    elsif (-d $arc_path) { 
     say $fh_out "$_ IN_ARCHIVE"; 
    } 
    else { 
     say $fh_out "NA"; 
    } 
} 
close $fh; 
close $fh_out; 

# Changes inode number. See text for comment 
move($fh_out, $fh) or die "Can't move $fh_out to $fh: $!"; 

正則表達式匹配最多到第一_,由於?使得.*?非貪婪(它停止在第一_)。然後它捕獲一切,直到最後_由於.*是貪婪的,匹配一切,直到最後_。通過使用rindex,這就是問題中的代碼。然後它捕獲所有的標籤/空格。

然後打印當前行,如同在問題中一樣附加到輸出文件。由於輸出文件是臨時的,因此其名稱應該使用File::Temp構建。然後使用File::Copy重命名該文件。

這改變了inode號碼。如果這很重要,保持inode號碼的一種方法如下。在輸出文件被寫出後,打開的原文件,什麼會打開它。然後從輸出文件中讀取並寫入原始文件。內容被複制到相同的inode。完成後刪除輸出文件。在開始鏈接的帖子中查看更多細節。

+0

非常感謝你的建議...它的工作原理 –

+0

@Perlnewbie很棒:)讓我知道是否有問題 – zdim

相關問題