Раскомментируйте блок текста с помощью awk или sed

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

Lorem ipsum dolor sit amet, nullam euismod tractatos id mel, has integre ornatus 
feugait ad. In eum enim putent fierent. Quo melius persecuti conceptam eu, ne probo 
autem inciderint quo, ius et atqui diceret. Causae prompta corpora ex ius. Atqui 
aperiri in duo, ex pro reque utinam.

Sea ne prima falli petentium. Ut has ancillae omnesque lucilius, vim ex alia 
audire contentiones. Error possit singulis at his. Ne purto soleat ius, detracto 
sententiae mel ne. Te eos regione detracto, eam quas accumsan detracto an.

  # Lorem ipsum dolor sit amet, nullam euismod tractatos id mel, has integre ornatus 
  # feugait ad. In eum enim putent fierent. Quo melius persecuti conceptam eu, ne probo 
  # autem inciderint quo, ius et atqui diceret. Causae prompta corpora ex ius. Atqui 
  # aperiri in duo, ex pro reque utinam.

  # Comment
  # At debet expetenda sed, sed te case ceteros adolescens. Ad sea facer minim tempor, 
  # eam facilisi definitiones ei, vix vidit erant dissentias et. Eum fierent scaevola 
  # suscipiantur eu. Eum essent platonem interesset ex, ut idque vidisse nam, labores 
  # intellegam comprehensam eos et. Eu eum appetere sententiae percipitur, ad eam hinc 
  # impetus sententiae, pro duis consetetur reprehendunt in. Id percipit iracundia 
  # abhorreant est.

  # Sea ne prima falli petentium. Ut has ancillae omnesque lucilius, vim ex alia 
  # audire contentiones. Error possit singulis at his. Ne purto soleat ius, detracto 
  # sententiae mel ne. Te eos regione detracto, eam quas accumsan detracto an.

Lorem ipsum dolor sit amet, nullam euismod tractatos id mel, has integre ornatus 
feugait ad. In eum enim putent fierent. Quo melius persecuti conceptam eu, ne probo 
autem inciderint quo, ius et atqui diceret. Causae prompta corpora ex ius. Atqui 
aperiri in duo, ex pro reque utinam.

Sea ne prima falli petentium. Ut has ancillae omnesque lucilius, vim ex alia 
audire contentiones. Error possit singulis at his. Ne purto soleat ius, detracto 
sententiae mel ne. Te eos regione detracto, eam quas accumsan detracto an.

Я хочу использовать либо AWK, либо SED, чтобы раскомментировать следующие 3 строки после строки # Comment, чтобы она выглядела так:

  # Comment
  At debet expetenda sed, sed te case ceteros adolescens. Ad sea facer minim tempor, 
  eam facilisi definitiones ei, vix vidit erant dissentias et. Eum fierent scaevola 
  suscipiantur eu. Eum essent platonem interesset ex, ut idque vidisse nam, labores 
  # intellegam comprehensam eos et. Eu eum appetere sententiae percipitur, ad eam hinc 
  # impetus sententiae, pro duis consetetur reprehendunt in. Id percipit iracundia 
  # abhorreant est.

Пожалуйста, объясните свое решение, чтобы я мог узнать и понять. Мои знания AWK и SED все еще находятся на начальном уровне.


person Tuaris    schedule 10.10.2015    source источник
comment
Белые пространства должны быть сохранены.   -  person Tuaris    schedule 10.10.2015
comment
Подойдет ли Perl-ответ?   -  person melpomene    schedule 10.10.2015


Ответы (2)


awk считает строки в своей NR переменной.

awk '/# Comment/ {n=NR}
     n && NR-n && NR-n<=3 {sub("# ?","")}
     {print}'

n=NR фиксирует номер строки, в которой встречается # Comment

Ноль эквивалентен false, а ненулевое значение true в awk, поэтому в условном выражении: 1) n предотвращает начало раскомментации в начале файла, 2) NR-n предотвращает начало раскомментирования в строке # Comment, и 3) NR-n<=3 определяет строки, в которых действительно происходит раскомментирование.

Функция sub - это однократная подстановка строки в awk. Строка, которая должна быть заменена на "", т.е. удалена, представляет собой символ комментария #, за которым следует ноль или один пробел - ? - это квантификатор регулярного выражения для "необязательного" (ноль или один).

person Jeff Y    schedule 10.10.2015

Вот моя попытка использовать GNU sed (это, вероятно, не будет работать с другими версиями sed):

sed '/^  # Comment$/,+3 { s/^  # /  /; s/^  Comment$/  # Comment/ }'

Мы сопоставляем все строки, начинающиеся со строки, равной " # Comment", и следующих 3 строк (часть +3 является расширением GNU, как сказано в моем руководстве).

В этих строках мы заменяем начальный " # " всего двумя пробелами, " ", таким образом раскомментируя строку.

Однако это также влияет на начальную линию, которую вы не хотели раскомментировать. Итак, мы исправляем это после: Если в результате получается строка " Comment", мы снова добавляем "# ".

person melpomene    schedule 10.10.2015
comment
Хм ... в моей системе возвращается ошибка: sed: 1: "/^ # Comment$/,+3 { s/ ...": bad flag in substitute command: '}' Вероятно, поскольку я использую BSD. - person Tuaris; 11.10.2015