2010-12-08 80 views
25

我想通過修改,刪除或插入行或追加到文件的開頭來更改文件的內容。我怎樣才能在Perl中做到這一點?在Perl中,如何更改,刪除或在文件中插入一行或追加到文件的開頭?


這是從一個official FAQquestion。我們是importing the perlfaq to Stack Overflow

+0

可能重複[如何更改,刪除或插入文件中的行,或追加到Perl文件的開頭?](http://stackoverflow.com/questions/2322140/)如何改變刪除或插入文件或追加到開始) – 2011-11-06 12:35:26

回答

41

(這是official perlfaq answer,減去任何後續編輯)

插入,更改或從文本文件 包括讀取和打印文件,以點刪除線的基本想法,你想使 更改,進行更改,然後讀取並打印文件的其餘部分。 Perl不提供對行的隨機訪問(特別是因爲記錄 輸入分隔符$/是可變的),儘管諸如 Tie::File等模塊可以僞造它。

一個Perl程序來完成這些任務需要打開一個文件, 打印其行,然後關閉該文件的基本形式:

open my $in, '<', $file  or die "Can't read old file: $!"; 
open my $out, '>', "$file.new" or die "Can't write new file: $!"; 

while(<$in>) 
    { 
    print $out $_; 
    } 

close $out; 

在這一基本形式,添加您需要插入部件,更改或 刪除行。

要在行首添加行,請在輸入打印現有行的 循環之前先打印這些行。

open my $in, '<', $file  or die "Can't read old file: $!"; 
open my $out, '>', "$file.new" or die "Can't write new file: $!"; 

print $out "# Add this line to the top\n"; # <--- HERE'S THE MAGIC 

while(<$in>) 
    { 
    print $out $_; 
    } 

close $out; 

要改變現有生產線,插入代碼以修改 內的線,而循環。在這種情況下,代碼會查找「perl」的所有小寫版本並將其大寫。每一行都會發生,所以請確保你是 應該在每一行都做到這一點!

open my $in, '<', $file  or die "Can't read old file: $!"; 
open my $out, '>', "$file.new" or die "Can't write new file: $!"; 

print $out "# Add this line to the top\n"; 

while(<$in>) 
    { 
    s/\b(perl)\b/Perl/g; 
    print $out $_; 
    } 

close $out; 

要僅更改特定的一行,輸入行號$。是有用的。 首先閱讀並打印您想要更改的行。接下來,請閱讀 您想要更改的單行,更改並打印它。在此之後, 讀線的休息和打印這些:

while(<$in>) # print the lines before the change 
    { 
    print $out $_; 
    last if $. == 4; # line number before change 
    } 

my $line = <$in>; 
$line =~ s/\b(perl)\b/Perl/g; 
print $out $line; 

while(<$in>) # print the rest of the lines 
    { 
    print $out $_; 
    } 

要跳過的行,使用循環控制。此示例中的下一個將跳過 註釋行,並且最後一次遇到 __END____DATA__時會停止所有處理。

while(<$in>) 
    { 
    next if /^\s+#/;    # skip comment lines 
    last if /^__(END|DATA)__$/; # stop at end of code marker 
    print $out $_; 
    } 

做同樣的事情用旁邊跳過 你不想在輸出中顯示的行刪除特定行。這個例子跳過每 第五行:

while(<$in>) 
    { 
    next unless $. % 5; 
    print $out $_; 
    } 

如果出於某種奇怪的原因,你真的想看到整個文件一次 ,而不是加工生產線,由線,您可以在思樂普它(只要因爲你可以 適合整個內存!):

open my $in, '<', $file  or die "Can't read old file: $!" 
open my $out, '>', "$file.new" or die "Can't write new file: $!"; 

my @lines = do { local $/; <$in> }; # slurp! 

    # do your magic here 

print $out @lines; 

模塊,例如File::SlurpTie::File可以與 過幫助。但是,如果可以,請避免一次讀取整個文件。 Perl不會 將該內存返回給操作系統,直到該過程完成。

您還可以使用Perl one-liners來就地修改文件。以下 將inFile.txt中的所有'Fred'更改爲'Barney',並使用 新內容覆蓋該文件。使用-p開關時,Perl圍繞您用-e指定的代碼 包裝一個while循環,並且-i開啓就地編輯。當前 行在$_。使用-p,Perl會在循環結束時自動輸出$_的值 。有關更多詳細信息,請參閱perlrun

perl -pi -e 's/Fred/Barney/' inFile.txt 

爲了inFile.txt的備份,給-ia文件擴展名補充:

perl -pi.bak -e 's/Fred/Barney/' inFile.txt 

要改變只有第五行,你可以添加一個測試檢查$.,輸入 線之前

perl -pi -e 's/Fred/Barney/ if $. == 5' inFile.txt 

在一定行之前添加行,可以添加一行:數,然後僅當測試通過執行該操作(或行!)個Perl的打印$_

perl -pi -e 'print "Put before third line\n" if $. == 3' inFile.txt 

你甚至可以 打印在循環的末尾添加一行到文件的開頭,因爲當前行:

perl -pi -e 'print "Put before first line\n" if $. == 1' inFile.txt 

後插入一行一個已經在文件中,使用-n開關。它與-p一樣是 ,只是它在循環結束時不打印$_,所以 您必須自己做。在這種情況下,首先打印$_,然後打印要添加的 行。

perl -ni -e 'print; print "Put after fifth line\n" if $. == 5' inFile.txt 

要刪除行,只打印所需的行。

perl -ni -e 'print unless /d/' inFile.txt 

&hellip;或者......

perl -pi -e 'next unless /d/' inFile.txt 
+0

'perl -ni -e'print除非/ d /'inFile .txt`確實可以刪除匹配的行,但是`perl -pi -e'next除非/ d /'inFile.txt`沒有。如果不是`下一步',也不會改變'下一步'。這是與perl 5.10.0。任何想法發生了什麼? – 2014-10-03 00:19:17

相關問題