【问题标题】:Open file for reading and writing(not appending) in perl在 perl 中打开文件进行读写(不附加)
【发布时间】:2011-05-27 18:26:27
【问题描述】:

标准 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
    }
}

【问题讨论】:

  • 1k + 观看次数,只有 1 次赞成。 . .

标签: perl file file-io


【解决方案1】:

您已经通过使用&lt;+ 模式打开文件进行读取和写入,您只是没有对它做任何有用的事情——如果您想替换文件的内容而不是写入当前文件位置(文件的结尾),那么您应该 seek 回到开头,写下您需要的内容,然后 truncate 以确保如果您将文件缩短,则不会留下任何内容。

但是由于您要对文件进行就地过滤,我是否建议您使用 perl 的就地编辑扩展,而不是自己完成所有工作?

#!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 的程序没有任何作用,binmodeing stdin 和 stdout 对从不使用 stdin 或 stdout 的程序没有任何作用,节省CWD 对从来没有chdirs 的程序没有任何作用。没有理由一次读取每个文件,所以我将其更改为 linewise,并使正则表达式不那么尴尬(顺便说一句,/o 正则表达式修饰符如今几乎没有什么用处,除了添加难以 -查找代码中的错误)。

【讨论】:

  • @hobbs,该过程是基于行的。如果我想使用包含换行符的正则表达式怎么办?
  • @solotim 取决于细节。您可能能够将$/ 更改为比"\n" 更合适的东西——特别是,如果您将$/ 设置为undef,那么 perl 将一次读取整个文件内容,让您修改它们,然后写回来。内存足够大,对于许多文件来说这是一种合理的方法。但如果不是,您将需要自己完成这项工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-08
  • 2011-10-02
  • 2019-12-20
  • 2019-06-25
  • 1970-01-01
  • 1970-01-01
  • 2021-10-20
相关资源
最近更新 更多