как заменить следующую строку после совпадения (каждых) двух пустых строк?

есть ли способ сделать такую ​​замену в Awk, sed, ...?

У меня есть текстовый файл с разделами, разделенными на две пустые строки;

   section1_name_x
   dklfjsdklfjsldfjsl


   section2_name_x
   dlskfjsdklfjsldkjflkj


   section_name_X
   dfsdjfksdfsdf

Я бы заменил каждое «section_name_x» на «# section_name_x», то есть как заменить следующую строку после совпадения (каждых) двух пустых строк?

Спасибо,

Стив,


person Steve    schedule 28.12.2013    source источник


Ответы (2)


hm....

Учитывая данные вашего примера, почему бы просто не

sed 's/^section[0-9]*_name.*/#/' file > newFile && mv newFile file

некоторые sed поддерживают sed -i ИЛИ sed -i"" для перезаписи существующего файла, избегая показанного выше && mv ....

В регулярном выражении говорится, что раздел должен быть в начале строки и может содержать число или НИКАКОЕ число.

IHTH

person shellter    schedule 28.12.2013

В gawk вы можете использовать встроенную переменную RT:

gawk '{$1="#"$1; print $0 RT}' RS='\n\n' file

* Обновление *

Благодаря @EdMorton я понял, что моя первая версия была неверной. Что просходит:

  • Присвоение $1 приводит к перестроению записи, что в данном случае нехорошо, поскольку любая последовательность пробелов заменяется одиночным пробелом между полями и нулевой строкой в ​​начале и в конце записи.
  • Использование print добавляет к выходным данным дополнительную новую строку.

Правильная версия:

gawk '{printf "%s", "#" $0 RT}' RS='\n\n\n' file
person Håkon Hægland    schedule 28.12.2013
comment
Просто имейте в виду, что это заменит все цепочки пробелов в имени раздела одним пробелом. Почему бы не просто '{print "#" $0 RT}'? Кроме того, скрипт не ищет 2 пустые строки, а только 1, поскольку первая \n находится в конце непустой строки. Вам нужно использовать RS='\n\n\n', а затем либо установить ORS="", либо использовать printf вместо print для вывода. - person Ed Morton; 28.12.2013
comment
@EdMorton Спасибо за комментарий. Я полностью согласен с вашим первым комментарием. Присвоение $1 будет занимать пробелы вокруг каждого поля, поэтому я не собирался этого делать. Однако я проверил ваш второй комментарий относительно RS='\n\n' или RS='\n\n\n', и это правильно, что в файле есть три новых символа строки, но это похоже, что один из них съеден FS, так что RS='\n\n' действительно работает.. - person Håkon Hægland; 28.12.2013
comment
Нет, это просто КАЖЕТСЯ работать, потому что оно соответствует первым 2 \ns, а затем оставляет 3-й как начало следующей записи, а затем присваивание $1 приводит к перекомпиляции записи для удаления начальных пробелов. это комбинация двух ошибок, скрывающих друг друга. Попробуйте это с вводом, который имеет только 1 пустую строку между записями вместо 2, и вы увидите, что ваш сценарий ошибочно считает, что только одна пустая строка является приемлемым RS. - person Ed Morton; 29.12.2013
comment
Да, так и будет. Я бы написал это как printf "#%s%s", $0, RT, но в любом случае это сработает. - person Ed Morton; 29.12.2013