2016-06-30 4 views
0

У меня есть несколько файлов (*.txt), которые мне нужно удалить. Файлы выглядят следующим образом:Удаляет несколько строк из нескольких файлов несколько раз

This is a line to keep. 
keep me too 
START 
some stuff to remove 
other to remove 
END 
keep me! 

И я хочу, чтобы выглядеть следующим образом:

This is a line to keep. 
keep me too 
keep me! 

Я получил это далеко:

perl -i -p0e 's/#START.*?END/ /s' file.txt 

Какой будет удалить первый экземпляр что от file.txt, но я не могу понять, как удалить все экземпляры с file.txt (а затем как применить это ко всем *.txt файлам?)

+0

Это просто, но это должен быть однострочный? Должны ли файлы быть изменены на месте, или новые, написанные, или вы хотите получить только один большой файл? – zdim

+0

Спасибо @zdim Нет, это не должно быть однострочным. Меня не волнует, изменились ли они на месте или нет, и я хочу, чтобы отдельные файлы были выходными. – Alex

ответ

4

Если то, что вы показать работы по первой инстанции, все, что вам нужно нужно добавить это /g флага, чтобы сделать все экземпляры и оболочки Глобы, чтобы выбрать все файлы .txt:

perl -i -p0e 's/#START.*?END/ /gs' *.txt 
+0

Спасибо. Я попытался добавить флаг '/ g', но он просто удалил все файлы.Однако это работает, поэтому я, должно быть, раньше делал что-то неправильно. Благодаря тонну! – Alex

3

Это кажется быть право на flip-flop operator

#!/usr/bin/env perl 

use strict; 
use warnings; 

while(<DATA>) { 
    print unless (/^START/ .. /^END/); 
} 

__DATA__ 
This is a line to keep. 
keep me too 
START 
some stuff to remove 
other to remove 
END 
keep me! 

Выход:

This is a line to keep. 
keep me too 
keep me! 

Он также может быть записан в виде однострочника:

perl -n -e 'print unless (/^START/ .. /^END/);' input.txt > output.txt 

Или, чтобы редактировать файлы на месте:

perl -n -i -e 'print unless (/^START/ .. /^END/);' *.txt 
+0

Вы должны добавить версию своего сценария в командной строке. –

+0

@CasimiretHippolyte Вы правы. Спасибо. Обновлен мой ответ. – PerlDuck

1

бухгалтерской вещь, чтобы заботиться здесь открытие и написание отдельные файлы. Сама обработка обрабатывается range operator.

use warnings; 
use strict; 

my @files = @ARGV; 

my ($fh_in, $fh_out); 

foreach my $file (@files) 
{ 
    my $outfile = "new_$file"; 

    open $fh_in, '<', $file or die "Can't open $file: $!"; 
    open $fh_out, '>', $outfile or die "Can't open $outfile: $!"; 

    print "Processing $file, writing to $outfile.\n"; 

    while (<$fh_in>) { 
     print $fh_out $_ if not /^START$/ .. /^END$/; 
    } 
} 

Эта ссылка используется как script.pl file-list.

Поскольку мы используем тот же дескриптор файла для чтения (и тот же, что и для записи), когда новый файл открыт, предыдущий закрывается, см. perlopentut и open. Таким образом, мы не должны close

Вы не должны закрывать FILEHANDLE, если вы сразу же собираетесь делать еще один открытый на нем, потому что открытая закрывает его для вас. (См. Открытый.)

Я называю новые файлы new_$file, чтобы предоставить рабочий образец. Например, вы можете переименовать старый код в $file.orig, а вместо него - $file, после цикла while. Для этого я использовал бы функции из основного модуля File::Copy. В этом случае нам нужно сначала закрыть файлы.

Смежные вопросы