從perlfaq5的答案How do I change, delete, or insert a line in a file, or append to the beginning of a file?
從一個文本文件中插入,更改或刪除線的基本思想包括閱讀並將文件打印到您想要進行更改的位置,進行更改,然後閱讀並打印文件的其餘部分樂。 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 $_;
}
接近$出; 在該基本表單中,添加您需要插入,更改或刪除行的部分。
要在行首添加行,請在輸入打印現有行的循環之前打印這些行。
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; 要更改現有行,請插入代碼以修改while循環內的行。在這種情況下,代碼將查找所有小寫版本的「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 $_;
}
做同樣的事情來刪除一個特定的行,使用next來跳過你不想顯示在輸出中的行。只要
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 :: Slurp的和領帶::文件可以提供幫助的了。但是,如果可以,請避免一次讀取整個文件。在這個過程完成之前,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
... or ...
perl -pi -e 'next unless /d/' inFile.txt
您可能想要爲該第二個正則表達式添加'/ i'修飾符以及... – 2010-02-22 22:48:56
謝謝!唯一缺少的是在'if'語句中的'$ fho'後面的'$ _'(花了我一段時間才發現,實際上...) – ryantmer 2010-02-22 22:55:19
@ryantmer:是的,我的代碼沒有經過測試。我更新了我的帖子。我懶得創建任何虛假輸入來測試我的代碼,這就是爲什麼提供一個小樣本輸入與您的問題是一個好主意。 – toolic 2010-02-22 23:41:50