удалить элементы из файла с помощью Perl - PullRequest
1 голос
/ 12 августа 2011

Input.txt

CASE
    REPEAT 1 TIMES
    ENDREPEAT
ENDCASE
    REPEAT
    ENDREPEAT
CASE
    REPEAT 2 TIMES
    ENDREPEAT
ENDCASE

code.pl

open (FH, "input.txt");
my @arr = <FH>;

foreach (@arr) {
    if ($_ =~ s/ENDCASE.*?CASE//gsi) {
       $_ = s/ENDCASE.*?CASE//gsi;
    }
}
print @arr;

Вывод: perl code.pl

Печатает массив без изменения ........

CASE
    REPEAT 1 TIMES
    ENDREPEAT
ENDCASE
    REPEAT        ===> To be Removed
    ENDREPEAT     ===> To be Removed
CASE
    REPEAT 2 TIMES
    ENDREPEAT
ENDCASE

Требуется вывод: *** |||||||||||| ****

CASE
    REPEAT 1 TIMES
    ENDREPEAT
ENDCASE
************Content Removed*****************
CASE
    REPEAT 2 TIMES
    ENDREPEAT
ENDCASE

Пожалуйста, помогите мне получить этот вывод.

Заранее спасибо .........

Ответы [ 4 ]

4 голосов
/ 12 августа 2011

Это можно сделать также через командную строку à la оператор триггера .


Чтобы вывести результат на экран

$ perl -ne 'print if /^CASE/ .. /^ENDCASE/' Input.txt

Чтобы перенаправить вывод в другой файл

$ perl -ne 'print if /^CASE/ .. /^ENDCASE/' Input.txt > output.txt

Для изменения файла на месте

$ perl -ni.bak -e 'print if /^CASE/ .. /^ENDCASE/' Input.txt

Заменить ' (одинарные кавычки) на " (двойные кавычки), если в Windows.

1 голос
/ 12 августа 2011

У вас есть несколько предложений о способах решения вашей проблемы, но вам может быть интересно узнать, почему ваше решение не работает.Есть несколько причин.

Во-первых, когда вы читаете свой файл в @arr, вы получаете одну строку файла в каждом элементе массива.И когда вы обрабатываете массив элемент за раз, ни один элемент не содержит ни ENDCASE, ни CASE, поэтому ваше регулярное выражение никогда не совпадает и ничего не меняется.весь файл за один раз.(Я также немного очистил ваш код.)

#!/usr/bin/perl

use strict;
use warnings;

open (my $fh, '<', 'input.txt') or die $!;
my $file = do { local $/; <$fh> };

$file =~ s/ENDCASE.*?CASE//gsi;

print $file;

Но это не решает проблему.Это дает вывод:

CASE
    REPEAT 1 TIMES
    ENDREPEAT

    REPEAT 2 TIMES
    ENDREPEAT
ENDCASE

Это потому, что ENDCASE и CASE включены в ваше регулярное выражение, поэтому они удаляются.Чтобы решить эту проблему, вам нужно взглянуть на утверждения в виде заглядывания вперед и назад в perlre .Я оставлю это как упражнение для читателя.

0 голосов
/ 12 августа 2011

Вот странная идея, которая может сработать.

use English qw<$INPLACE_EDIT $RS>;
$INPLACE_EDIT = '.bak';
local $RS     = "CASE\n";

while ( <$input> ) {
    print(( !/^(END)?CASE\n\z/ms or $1 ) ? $_ : $RS );
}

Идея состоит в том, что вы разбиваете свои записи не по новым строкам, а по CASE + \n, и, таким образом, вы обрабатываете все строкимежду ENDCASE и CASE как одной записью, которую вы можете просто заменить на "CASE\n".

Обратите внимание, что мы просто печатаем запись, если не видим начала строки перед «ENDCASE» или «CASE», за которой следует новая строка,Таким образом, даже если мы делаем довольно хрупкое предположение, когда разбиваем записи, мы проверяем наше предположение, прежде чем изменять запись.Также, если оно соответствует "ENDCASE\n", тогда $1 равно 'END', и мы печатаем эту запись без изменений.

Однако может сломаться.Если по какой-то причине у вас есть возможность получить комментарий здесь:

ENDCASE
    REPEAT       ===> This prints because it ends with CASE
    ENDREPEAT     
CASE

Тогда будет напечатана первая строка.Таким образом, мы могли бы сделать это:

my $match = 0;
my $old_1;
while ( <$input> ) {
    if ( m/^(END)?CASE\n\z/ms and not $1 ) {
        print $RS;
    }
    else {
        next if $old_1;
        print;
    }
    $old_1 = $1;
}    
0 голосов
/ 12 августа 2011

Свяжите ваш файл, используя Tie :: File :

tie @array, 'Tie::File', filename or die ...;

Управляйте строками любым удобным для вас способом, а затем развяжите массив:

untie @array;   

Таким образом, ваши изменения будут отражены в исходном файле.

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