标准的perl库是否有任何方法可以打开文件并对其进行编辑,而无需关闭它然后再打开它?我所知道的只是将文件读入一个字符串中关闭文件,然后用一个新文件覆盖该文件;或者读取然后附加到文件的末尾。
以下目前有效;我必须打开它并关闭它两次,而不是一次:
#!/usr/bin/perl
use warnings; use strict;
use utf8; binmode(STDIN, ":utf8"); binmode(STDOUT, ":utf8");
use IO::File; use Cwd; my $owd = getcwd()."/"; # OriginalWorkingDirectory
use Text::Tabs qw(expand unexpand);
$Text::Tabs::tabstop = 4; #sets the number of spaces in a tab
opendir (DIR, $owd) || die "$!";
my @files = grep {/(.*)\.(c|cpp|h|java)/} readdir DIR;
foreach my $x (@files){
my $str;
my $fh = new IO::File("+<".$owd.$x);
if (defined $fh){
while (<$fh>){ $str .= $_; }
$str =~ s/( |\t)+\n/\n/mgos;#removes trailing spaces or tabs
$str = expand($str);#convert tabs to spaces
$str =~ s/\/\/(.*?)\n/\/\*$1\*\/\n/mgos;#make all comments multi-line.
#print $fh $str;#this just appends to the file
close $fh;
}
$fh = new IO::File(" >".$owd.$x);
if (defined $fh){
print $fh $str; #this just appends to the file
undef $str; undef $fh; # automatically closes the file
}
}
答案 0 :(得分:15)
您已经使用模式<+
打开文件进行读写,您只是没有对它做任何有用的事情 - 如果您想要替换文件的内容而不是写入当前位置(文件末尾)然后您应该seek
回到开头,写下您需要的内容,然后truncate
以确保如果您缩短文件时没有遗留任何内容
但是,由于你要做的是对文件进行过滤,我是否可以建议您使用perl的inplace编辑扩展,而不是自己完成所有工作?
#!perl
use strict;
use warnings;
use Text::Tabs qw(expand unexpand);
$Text::Tabs::tabstop = 4;
my @files = glob("*.c *.h *.cpp *.java");
{
local $^I = ""; # Enable in-place editing.
local @ARGV = @files; # Set files to operate on.
while (<>) {
s/( |\t)+$//g; # Remove trailing tabs and spaces
$_ = expand($_); # Expand tabs
s{//(.*)$}{/*$1*/}g; # Turn //comments into /*comments*/
print;
}
}
这就是你需要的所有代码 - perl处理其余的代码。设置$^I variable等同于使用-i commandline flag。我对代码进行了一些更改 - use utf8
对源代码中没有文字UTF-8的程序没有任何作用,binmode
stdin和stdout对从不使用stdin的程序没有任何作用或者stdout,保存CWD对于从不chdir
s的程序没有任何作用。没有理由一次性读取所有文件所以我将其更改为linewise,并使正则表达式不那么笨拙(顺便说一句,/o
正则表达式修饰符现在几乎没有任何好处,除了添加硬 - 找到代码中的错误。)