From perlfaq5 http://faq.perl.org/perlfaq5.html#How_do_I_change_dele:
从文本文件中插入、更改或删除行的基本思想包括读取并打印文件到要进行更改的位置,进行更改,然后读取并打印文件的其余部分。 Perl 不提供对行的随机访问(特别是因为记录输入分隔符,$/
,是可变的),尽管诸如领带::文件 http://search.cpan.org/perldoc?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;
要更改现有行,请插入代码以修改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 $_;
}
要跳过行,请使用循环控件。这next
在此示例中跳过注释行,并且last
一旦遇到任何一个,就停止所有处理__END__
or __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;
模块如文件::啜饮 http://search.cpan.org/perldoc?File::Slurp and 领带::文件 http://search.cpan.org/perldoc?Tie::File也可以提供帮助。但是,如果可以的话,请避免一次读取整个文件。在进程完成之前,Perl 不会将内存返还给操作系统。
您还可以使用 Perl 语句就地修改文件。以下将所有“Fred”更改为“Barney”inFile.txt
,用新内容覆盖文件。随着-p
switch,Perl 包装了一个while
循环您指定的代码-e
, and -i
打开就地编辑。当前行位于$_
. With -p
, Perl 自动打印的值$_
在循环的末尾。看perlrun http://perldoc.perl.org/perlrun.html更多细节。
perl -pi -e 's/Fred/Barney/' inFile.txt
进行备份inFile.txt
, give -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