Как мне найти два последовательных символа новой строки (\ n), используя perl? - PullRequest
1 голос
/ 31 января 2012

Как мне найти два последовательных символа новой строки (\ n), используя perl? Или, более конкретно, почему поиск \ n \ n не успешен, даже если он существует? У меня есть файл с последовательными символами новой строки (проверенный с помощью шестнадцатеричного редактора, они не возвращаются и т. Д.), Но Perl, похоже, не принимает это регулярное выражение.

perl -pi -e 's / \ n \ n / TEST / g' myfile.xml = нет результатов

На самом деле я пытаюсь вставить немного кода в XML-файлы, но перевод строки находится посередине, какой самый элегантный способ сделать это? Я придумал чудовищный perl one liner, но двухсторонние переводы, кажется, вызывают сбой.

Я хочу изменить часть файла gtkrc с:

GtkWidget::link-color = @link_color
GtkWidget::visited-link-color = @text_color

####################
# Color Definitions
####################

до:

GtkWidget::link-color = @link_color
GtkWidget::visited-link-color = @text_color

GtkWindow::resize-grip-height = 0
GtkWindow::resize-grip-width = 0

####################
# Color Definitions
####################

Используя часть исходного кода в качестве поискового запроса (кстати, перед каждой строкой в ​​исходном скрипте есть вкладки), мои термины поиска и замены были следующими:

color\n\n\t\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n\t\# Color

color\n\n\tGtkWindow::resize-grip-height = 0\n\tGtkWindow::resize-grip-width = 0\n\n\t\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n\t\# Color

Я придумал эту большую уродливую команду perl:

perl -pi -e 's/color\n\n\t\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n\t\# Color/color\n\n\tGtkWindow::resize-grip-height = 0\n\tGtkWindow::resize-grip-width = 0\n\n\t\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n\t\# Color/g' /usr/share/themes/Ambiance/gtk-2.0/gtkrc

РЕДАКТИРОВАТЬ: Исправленный код от Zaid:

perl -0777 -pi -e 's/color\n\n\t\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n\t\# Color/color\n\n\tGtkWindow::resize-grip-height = 0\n\tGtkWindow::resize-grip-width = 0\n\n\t\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n\t\# Color/g' /usr/share/themes/Ambiance/gtk-2.0/gtkrc

Как уже упоминалось, похоже, \ n \ n вызывает проблемы, поскольку все остальное можно заменить. Какой лучший способ сделать это?

Я нахожусь на Ubuntu 11.10, команда будет запускаться из сценария оболочки, а не из сценария perl.

Ответы [ 2 ]

3 голосов
/ 31 января 2012

Вам нужно загрузить весь файл за один снимок, чтобы \n\n был обнаружен. Используйте -0777, чтобы переопределить построчное поведение по умолчанию:

$ perl -0777 -pi -e 's/\n\n/TEST/g' myfile.xml
2 голосов
/ 31 января 2012

Когда вы открываете файл для чтения, файл по умолчанию читается построчно. Это потому, что разделитель входной записи $/ установлен на новую строку.

Поскольку вы разбиваете каждую «строку» на новой строке, очевидно, что вы никогда не найдете две строки в одной строке.

Один из способов обойти это, как сказал Заид, изменить разделитель входных записей с флагом -0. Пока новый разделитель входных записей не соответствует вашему регулярному выражению, все будет в порядке. (Пока вы не пытаетесь сопоставить . с \n).

Давайте сделаем ваше регулярное выражение немного менее ужасным. Вам не нужно экранировать #, если вы не используете модификатор /x. Вам не нужно использовать несколько # символов подряд, используйте квантификатор +, * or {x,y}.

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

  • Вы можете избежать удаления строки, используя Lookaround Assertions .
  • Вы можете использовать \K в качестве упрощенного утверждения о проверке (см. Выше)
  • Вы можете захватить строки и вернуть их обратно, используя $1, $2 ....

В этом случае я предпочел бы использовать утверждение для поиска строки «color \ n \ n», а затем для поиска комментария «Color».

perl -0777 -pwe 's/(?<=color\n\n)(?=[#\s]+Color)/INSERT\n\n/' /path/to/file 

Где INSERT - это, конечно, ваш текст для вставки, который я удалил для удобства чтения. Я также убрал флаг -i, чтобы вы могли сначала попробовать его.

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