Открыть файл для чтения и записи (не добавляя) в Perl - PullRequest
8 голосов
/ 19 декабря 2010

Есть ли какой-нибудь способ со стандартными библиотеками 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
    }
}

1 Ответ

15 голосов
/ 19 декабря 2010

Вы уже открыли файл для чтения и записи, открыв его в режиме <+, вы просто не делаете с ним ничего полезного - если вы хотите заменить содержимое файла вместо записи в текущийположение (конец файла), затем вы должны 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 эквивалентна использованию флага -i командной строки .Я сделал несколько изменений в вашем коде по пути - use utf8 ничего не делает для программы без буквального UTF-8 в исходном коде, binmode включение stdin и stdout ничего не делает для программы, которая никогда не использует stdin или stdout, сохраняяCWD ничего не делает для программы, которая никогда не chdir с.Не было никакой причины читать каждый файл сразу, поэтому я изменил его на аналогичный, и сделал регулярные выражения менее неловкими (и, между прочим, модификатор регулярных выражений /o в наши дни почти бесполезен, за исключением добавления сложных длянайти ошибки в вашем коде).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...