您可以使用perlfaq5中相同的技术:如何更改、删除或插入文件中的一行,或在文件开头添加内容:
(由brian d foy贡献)
从文本文件中插入、更改或删除一行的基本思路是读取并打印文件直到要进行更改的位置,进行更改,然后读取并打印其余部分。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";
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 $out $_;
last if $. == 4;
}
my $line = <$in>;
$line =~ s/\b(perl)\b/Perl/g;
print $out $line;
while( <$in> )
{
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 跳过不想出现在输出结果中的行,执行相同的操作以删除特定行。以下示例跳过每 5 行:
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> };
print $out @lines;
模块如File::Slurp和Tie::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,给-i一个文件扩展名以添加:
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