сценарий оболочки: поиск и замена по нескольким строкам - PullRequest
4 голосов
/ 19 октября 2011

Я ищу способ поиска и замены в нескольких строках с помощью сценария оболочки. Вот что я пытаюсь сделать:

source:
[stuff before]
<!--WIERD_SPECIAL_COMMENT_BEGIN-->
  [stuff here, possibly multiple lines.
<!--WIERD_SPECIAL_COMMENT_END-->
[stuff after]    

target:
[stuff before]
[new content]
[stuff after]

Короче говоря, я хочу удалить комментарии и все, что между ними, и заменить новым контентом. По сути, я хочу выполнить простую команду sed для нескольких строк и, если возможно, просто с помощью некоторых базовых инструментов * nix, без дополнительного языка сценариев.

Ответы [ 3 ]

1 голос
/ 19 октября 2011

sed делает это просто отлично. Следующее настолько просто, насколько это возможно; если вам нужно извлечь что-то из строки разделителя до начала или после конца, это будет немного сложнее.

sed '/<!--WIERD_SPECIAL_COMMENT_BEGIN-->/,/<!--WIERD_SPECIAL_COMMENT_END-->/d' input >output

Если у вас есть какой-либо контроль над этим, исправьте написание "странно".

1 голос
/ 19 октября 2011

Если вам нужно сопоставить только полные строки, вы можете выполнить эту задачу с awk. Что-то вроде:

    awk -v NEWTEXT=foo 'BEGIN{n=0} /COMMENT_BEGIN/ {n=1} {if (n==0) {print $0}} /COMMENT_END/ {print NEWTEXT; n=0}' < myfile.txt

Если файл не очень хорошо отформатирован, с комментариями ту же строку, что и текст, который вы хотите сохранить или удалить, тогда я будет использовать perl, прочитать весь файл в одну строку, сделайте совпадение регулярного выражения и замените эту строку, затем запишите новую строку в новый файл. Это не так просто, и вам нужно написать скрипт perl для выполнения этой работы. Что-то вроде:

#!/usr/bin/perl
$newtext = "foo\nbar";
$/ = '';  # no input separator so whole file is read.
$s = <>;  # read whole file from stdin
$startPattern = quotemeta('<!--WIERD_SPECIAL_COMMENT_BEGIN-->');
$endPattern = quotemeta('<!--WIERD_SPECIAL_COMMENT_END-->');
$pattern = $startPattern . '.+' . $endPattern;
$s =~ s/$pattern/$newtext/sg;
print $s;
0 голосов
/ 14 января 2013

другое решение ... это можно сделать в одной строке, но с использованием регулярных выражений perl , с которыми мне легче работать, чем с sed или awk (громоздкие с многострочным сопоставлением и заменой):

perl -0 -i -pe 's/<!--WIERD_SPECIAL_COMMENT_BEGIN-->[\s\S]*<!--WIERD_SPECIAL_COMMENT_END-->/your new content here/gim' yourfile1.txt

обратите внимание, что при этом файл будет заменен новым, измененным содержимым.

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