Подтвердить что ты не робот

Многострочный поиск заменить на Perl

Я знаю, что такие вопросы задавались уже много раз. Причина, по которой я снова здесь, - это то, что я чувствую, что пропустил что-то простое и фундаментальное.

Возможно ли сделать эту процедуру поиска? Например, не открывая тот же файл дважды. Также приветствуются советы по скорости.

Обратите внимание, что это работает с многострочными совпадениями и заменяет также многострочные строки.

#!/bin/perl -w -0777

local $/ = undef;

open INFILE, $full_file_path or die "Could not open file. $!";
$string =  <INFILE>;
close INFILE;

$string =~ s/START.*STOP/$replace_string/sm;

open OUTFILE, ">", $full_file_path or die "Could not open file. $!";
print OUTFILE ($string);
close OUTFILE;
4b9b3361

Ответ 1

Этот вид поиска и замены может выполняться с помощью одного слоя, такого как

perl -i -pe 's/START.*STOP/replace_string/g' file_to_change

Для получения дополнительных способов выполнить одно и то же: . Для обработки многострочных поисков используется следующая команда -

perl -i -pe 'BEGIN{undef $/;} s/START.*STOP/replace_string/smg' file_to_change

Чтобы преобразовать следующий код из однострочного в perl-программу, просмотрите документацию perlrun.

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

#!/usr/bin/perl -pi
#multi-line in place substitute - subs.pl
use strict;
use warnings;

BEGIN {undef $/;}

s/START.*STOP/replace_string/smg;

Затем вы можете вызвать script с именем файла в качестве первого аргумента

$perl subs.pl file_to_change

Если вам нужен более мясистый script, где вы можете обрабатывать операции открытия/закрытия файла (не любим ли мы все эти "умственные" высказывания), посмотрите на пример в perlrun под -i [ расширение] переключатель.

Ответ 2

Извлечение краткого ответа из комментариев для всех, кто ищет быстрый однострочный текст, и причина, по которой Perl игнорирует их параметры RegEx из командной строки.

perl -0pe 's/search/replace/gms' file

Без аргумента -0 Perl построчно обрабатывает данные line-by-line, что приводит к сбою многострочного поиска.

Ответ 3

Принимая во внимание, что вы полностью обрабатываете содержимое файла:

local $/ = undef;

open INFILE, $full_file_path or die "Could not open file. $!";
$string =  <INFILE>;
close INFILE;

И затем выполните всю обработку с помощью $string, нет связи между тем, как вы обрабатываете файл и как обрабатываете содержимое. У вас возникнет проблема, если вы откроете файл для записи, прежде чем вы его прочтете, так как открытие файла для записи создает новый файл, отбрасывая предыдущее содержимое.

Если все, что вы пытаетесь сделать, это сохранить в отчетах open/close, а затем сделать как предложенный Джонатан Леффер. Если ваш вопрос касается многострочного поиска и замены, пожалуйста, уточните, в чем проблема.

Ответ 4

Возможно, вы захотите проверить этот Perl-скрипт, протестированный в бою (широко используемый в производстве) и имеющий довольно много функций, таких как:

  • выполнить несколько операций поиска-замены или запроса-поиска-замены
  • выражения поиска-замены могут быть даны в командной строке или прочитаны из файла обрабатывает несколько входных файлов
  • рекурсивно спуститься в каталог и выполнить несколько операций поиска/замены для всех файлов
  • определенные пользователем выражения perl применяются к каждой строке каждого входного файла при желании запустить в режиме абзаца (для многострочного поиска/замены)
  • интерактивный режим
  • пакетный режим
  • опционально резервное копирование файлов и нумерация резервных копий
  • сохранить режимы/владельца при запуске от имени пользователя root
  • игнорировать символические ссылки, пустые файлы, защищенные от записи файлы, сокеты, именованные каналы и имена каталогов
  • при желании заменить строки, совпадающие или не соответствующие заданному регулярному выражению

https://github.com/tilo/replace_string