Понимание шаблона регулярных выражений sed

#bash #sed

#bash #sed

Вопрос:

Я очень новичок в мире Linux и пытаюсь освоиться с основными командами. Просматривая один из сценариев, я заметил нижеприведенную строку, которую я не мог понять.

 sed -n -e 's|declare -x ||p' -e 's|^declare -ax* ([^=]*)='''(.*)'''.*$|1=2|p'
 

Просматривая справочные страницы SED amp; declare, я получил представление о флагах / параметрах, таких как -n и -e, но не уверен в приведенном выше шаблоне, подобном регулярному выражению, и что именно делает «p» в конце команды?

Попытался воспроизвести приведенную выше строку на сайте regex101, но безуспешно : (

Ответ №1:

Первое выражение просто удаляет любое declare -x .

Второй извлекает переменную и значение из declare -ax variable=value с некоторыми осложнениями вокруг цитирования. Это x необязательно (строго говоря, регулярное выражение допускает ноль или больше, но вы, вероятно, не ожидаете больше одного).

Более подробно,

  • s|regex|replacement| просто заменяет любое совпадение regex с replacement , используя | в качестве разделителя регулярных выражений вместо значения по умолчанию /
  • s|regex|replacement|p с p помощью флага печатается результирующая строка, если произошла замена; это часто сочетается с sed -n печатью только строк, в которых произошла замена.
  • 'whatever'''something'''more stuff' использует кавычки оболочки для представления буквальных одинарных кавычек в строке, заключенной в одинарные кавычки. Вы не можете экранировать одинарные кавычки внутри одинарных кавычек, поэтому для встраивания одинарных кавычек в строку, заключенную в кавычки, используется закрывающая одинарная кавычка, за которой следует буквальная одинарная кавычка с обратной косой чертой, за которой следует другая открывающая одинарная кавычка.
  • s/(something.*)other/1/ заменяет something or other на something or , где скобки с обратной косой чертой определяют группировку и 1 являются обратной ссылкой на текст, который соответствует первой группе, заключенной в скобки. Аналогично 2 относится ко второй группе в скобках и т. Д.

.* внутри круглых скобок на самом деле неправильно, если целью является захват строки, заключенной в одинарные кавычки; регулярное выражение должно соответствовать только символу, который не является одинарной кавычкой (или, в идеале, выражению, которое содержит буквальные одинарные кавычки в соответствии с объяснением выше).

https://regex101.com / не особенно подходит для sed регулярных выражений. Он не поддерживает диалект регулярных sed выражений (ближайший, вероятно, диалект ECMAScript, но вы все равно должны понимать различия) и не может сказать вам, что делает окружающий скрипт.

Комментарии:

1. Чтобы получить представление о том, как базовые (BRE) и расширенные регулярные выражения (ERE) используются в sed, в руководстве есть этот обзор

Ответ №2:

Это p флаг s команды. В моей системе это задокументировано не на man странице, а на info странице.

‘p’
, Если замена была произведена, затем выведите новое пространство шаблона.

''' Танец — это просто обычный способ вставки одинарной кавычки в параметр bash. Одинарные кавычки удаляются во время «удаления кавычек», и одинарные кавычки не могут быть вложенными. Итак, вам нужно закончить строку, заключенную в кавычки, экранировать кавычку и начать другую строку, заключенную в кавычки. Вы также можете найти альтернативу '"'"' в дикой природе.

Поэтому sed будет рассматривать это как параметр (я использовал традиционный / вместо | поскольку нет необходимости использовать | ):

 s/^declare -ax* ([^=]*)='(.*)'.*$/1=2/p
 

который выполняет поиск declare в начале строки ( ^ ), за которой следует пробел -a и, возможно x , или xx или xxx и т. Д.; За которым следует пробел и что-нибудь, кроме = , затем = , а затем действительно что-нибудь в одинарных кавычках. Нам все равно, что следует за последней одинарной кавычкой. Два любых значения запоминаются в 1 и 2 , и вся строка заменяется 1=2 , т. Е. declare -axxx Удаляется из нее, как и самые внешние одинарные кавычки. Если строка не соответствует регулярному выражению, ничего не печатается.

Комментарии:

1. sed Команда фактически удалит любые одинарные кавычки вокруг строки, из которой она извлекается declare -a — я действительно думал, что это ее главная цель.

2. @tripleee: Да, я заметил, еще редактируя ответ 🙂