Проблемы с печатью на Perl в новый файл - PullRequest
4 голосов
/ 26 мая 2011

Я хочу удалить все строки в текстовом файле, которые начинаются с HPL_ Я получил это и могу печатать на экране, но когда я пытаюсь записать в файл, я просто получаю последнюю строку измененного текста, напечатанную вновый файл.Любая помощь, пожалуйста!

open(FILE,"<myfile.txt"); 
@LINES = <FILE>; 
close(FILE); 
open(FILE,">myfile.txt"); 
foreach $LINE (@LINES) { 
@array = split(/\:/,$LINE); 


my $file = "changed";

open OUTFILE, ">$file" or die "unable to open $file $!";

print OUTFILE $LINE unless ($array[0] eq "HPL_");

} 
close(FILE); 
close (OUTFILE);




exit;

Ответы [ 3 ]

7 голосов
/ 26 мая 2011

Вы просто хотите удалить все строки, которые начинаются с HPL_?Это просто!

perl -pi -e 's/^HPL_.*//s' myfile.txt

Да, на самом деле это всего лишь одна строка.: -)

4 голосов
/ 26 мая 2011

Проблема с вашим кодом заключается в том, что вы открываете файл для вывода в цикле обработки строк, который, благодаря использованию формы открытия «>», открывает файл каждый раз для записи, стирая любой предыдущий контент.

Переместите вызов open () в начало вашего файла, над циклом, и оно должно работать.

Кроме того, я не уверен в ваших намерениях, но в строке 4В вашем примере вы снова открываете свой входной файл для записи (используя '>'), который также забивает все, что в нем содержится.

В качестве примечания, вы можете попробовать прочитать команду Perl grep (), которая предназначенаделать именно то, что вам нужно, как в:

#!/usr/bin/perl
use strict;
use warnings;

open(my $in, '<', 'myfile.txt') or die "failed to open input for read: $!";
my @lines = <$in> or die 'no lines to read from input';
close($in);

# collect all lines that do not begin with HPL_ into @result
my @result = grep ! /^HPL_/, @lines; 

open(my $out, '>', 'changed.txt') or die "failed to open output for write: $!";
print { $out } @result;
close($out);
4 голосов
/ 26 мая 2011

Если вы не хотите использовать однострочник, переписать часть «запись в файл» следующим образом:

my $file = "changed";
open( my $outfh, '>', $file ) or die "Could not open file $file: $!\n";
foreach my $LINE (@LINES) { 
  my @array = split(/:/,$LINE);
  next if $array[0] eq 'HPL_';
  print $outfh $LINE;
}
close( $outfh );

Обратите внимание, как вы open() пишете файл каждый разчерез петлю.Это приводит к тому, что файл содержит только последнюю строку, так как использование open() с > означает «перезаписать содержимое файла».Это основная проблема с вашим кодом в его нынешнем виде.

Редактировать: Кроме того, вы хотите очистить свой код.Используйте лексические дескрипторы файлов, как я показал.Всегда добавляйте три строки, которые tchrist разместил в верхней части каждой из ваших Perl-программ.Используйте версию с тремя операторами open().Не вносите весь файл в массив, так как если вы попытаетесь прочитать огромный файл, это может привести к нехватке памяти на вашем компьютере.Ваша программа может быть переписана как:

#!perl

use strict;
use autodie; 
use warnings FATAL => "all";

my $infile = "myfile.txt";
my $outfile = "changed.txt";

open( my $infh, '<', $infile );
open( my $outfh, '>', $outfile );
while( my $line = <$infh> ) {
    next if $line =~ /^HPL_/;
    print $outfh $line;
}
close( $outfh );
close( $infh );

Обратите внимание, что с use autodie вам не нужно добавлять or die ... к функции open(), так как прагма autodie обрабатывает это длявы.

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