#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: Да, я заметил, еще редактируя ответ 🙂