Как я заменяю несколько строк отдельным словом в файле (оперативная замена)?

Содержание моего filename файл как следует (например):

My block of line starts from here 
START
First line
second line
third line
END
and end to here for example.

Я хочу заменить блок строк между START и END только с отдельным словом, например, с SINGLEWORD. Как ниже:

My block of line starts from here 
SINGLEWORD
and end to here for example.

Я могу найти свой блок строк с использованием этой команды:

grep -Pzo "START(.|\n)*END" filename

И результат выполнения выше команды будет похож на это:

START
First line
second line
third line
END

Затем я использовал эту команду для объединения всех строк в одну строку:

LAST_RESULT | sed -e :a -e '/$/N; s/\n/ /; ta'

Затем я получу этот результат:

START First line second line third line END

И с моей последней командой LAST_RESULTS | sed 's/.*/SINGLEWORD/' Я изменяю их на "SINGLEWORD" и я получаю этот результат.

SINGLEWORD

Теперь то, что я хочу: Как я могу использовать эту команду (Или Вашу команду предложения) и замена (на месте) мой блок строк к слову "ОДНОСЛОВНОМУ"? И конечный результат будет похож на этот файл:

My block of line starts from here 
SINGLEWORD
and end to here for example.
9
задан 29 September 2017 в 04:45

3 ответа

Это может быть сделано очень легко в perl:

$ perl -i -p0e 's/START.*?END/SINGLEWORD/s' file
$ cat file
My block of line starts from here 
SINGLEWORD
and end to here for example. 

Объяснение

-0 наборы разделитель строки к пустому указателю

-p применяет сценарий, данный -e к каждой строке, и печатает ту строку

regexp модификатор:

  • /s строка Обработки как одна строка. Таким образом, изменитесь . для соответствия любому символу вообще, даже новая строка, которой обычно он не соответствовал бы.

, Почему ?:

  • По умолчанию, определенный количественно подшаблон является "жадным", то есть, он будет соответствовать максимально много раз (учитывая конкретное стартовое местоположение), все еще позволяя остальной части шаблона соответствовать. Если Вы хотите, чтобы он соответствовал минимальному возможному количеству раз, следовал за квантором с ?.
13
ответ дан 23 November 2019 в 04:46

Я задавался вопросом, возможно ли это без perl, python и другие. И я нашел это решение с помощью sed:

$ sed ':a;N;$!ba;s/START.*END/SINGLEWORD/g' filename

Объяснение:

  1. : создают маркирование
  2. N , добавляют следующую строку к пространству шаблона
  3. $! , если не последняя строка , ответвление ba (переходят в) маркируют
  4. s замену , /START.*END/ SINGLEWORD, /g глобальное соответствие (как много раз, как это может)

, Это было найдено здесь .

@KasiyA, спасибо я изучил много интересных вещей!

13
ответ дан 23 November 2019 в 04:46

Хотя ripgrep специально не поддерживает встроенную замену, я обнаружил, что его текущая функциональность --replace уже полезна для этот вариант использования:

rg --replace 'SINGLEWORD' --passthru --no-line-number \
--multiline --multiline-dotall 'START.*?END' input.txt > output.txt

Объяснение:

  • --replace 'SINGLEWORD' включает режим замены и устанавливает строку замены. Можно включить захваченные группы регулярных выражений, используя $1 и т. д.
  • --passthru необходим, поскольку ripgrep обычно показывает только строки, соответствующие шаблону регулярного выражения. С этой опцией он также показывает все строки из файла, которые не совпадают.
  • --no-line-number / -N потому, что по умолчанию ripgrep включает номера строк в вывод (полезно, когда отображаются только совпадающие строки).
  • --multiline / -U включил многострочную обработку, поскольку по умолчанию она отключена.
  • --multiline-dotall требуется только в том случае, если вы хотите, чтобы шаблон регулярного выражения с точкой ('.') соответствовал новой строке (\n).
  • > output.txt необходим, так как встроенная замена не поддерживается. С опциями --passthrough и no-line-number стандартный вывод соответствует желаемому новому файлу с заменами и может быть сохранен как обычно.

Однако эта команда не так полезна для обработки нескольких файлов, так как ее нужно запускать отдельно для каждого файла.

2
ответ дан 21 June 2020 в 16:47

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

Похожие вопросы: