Perl заменяет строки в определенных блоках в файле

Привет я пытаюсь заменить строки в файле test.txt на строки, подобные этим:

  <g
   id="g16526">
  <g

  <g
   id="gnnnnn">
  <g

и превратить их в

  <g
   id="gg1">
  <g
   ...
  <g
   id="ggn">
  <g

используя этот Perl-скрипт

    #!C:/Strawberry/perl
    open(FILE, "<test.txt") || die "File not found";
    my @lines = <FILE>;
    close(FILE);
    my $string = '<g
    id=';
    my $string2 = '<g
    <g'; 
    my $anything = ".*";

    my $replace = 'gg';
    my @newlines;
    my $counter = 1;

    foreach(@lines) {
      $_ =~ s/\Qstring$anything\Q$string2/$string$replace$string2$counter/g;
      $counter++;
      push(@newlines,$_);
    }

    open(FILE, ">test.txt") || die "File not found";
    print FILE @newlines;
    close(FILE);

но это не работает, любые предложения приветствуются

1 ответ

Решение

Если это действительно имеет XML-подобную структуру, как кажется, то ее следует обрабатывать с использованием модулей для этого, либо XML::LibXML, либо XML:: Twig.

Но эта задача, как показано, легко выполняется элементарным образом

perl -0777 -wpE'
    BEGIN { $cnt = 0 };
    s/<g\nid="g\K(.*?)"/q(g).(++$cnt).q(")/eg;
' input.txt

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

Другой способ - установить разделитель записей на <gпоэтому каждая "строка" является блоком для обработки

perl -wpE'
    BEGIN { local $/ = "<g"; $cnt = 0 }; 
    s/id="g\K(.*?)"/q(g).++$cnt.q(")/eg; 
' t.txt

где теперь регулярное выражение может искать именно id="..." и мы можем обрабатывать построчно.

Они оба печатают ожидаемый результат. Они в одной строке для облегчения тестирования, я предлагаю перейти к сценарию.

Другие вопросы по тегам