Понимание примера sed

Я нашел решение для извлечения пароля из элемента Keychain для Mac OS X. Он использует sed для получения пароля из команды security:

security 2>&1 >/dev/null find-generic-password -ga $USER | \ 
 sed -En '/^password: / s,^password: "(.*)"$,\1,p'

Код здесь в комментарии от 'sr105'. Часть перед | оценивается как password: "secret". Я пытаюсь выяснить, как работает команда sed. Вот несколько мыслей:

Я понимаю флаги -En, но что представляют собой запятые в этом примере? В sed docs говорится, что запятая разделяет диапазон адресов, но там 3 запятых.

Первый "адрес" /^password: / имеет конечный s; в документах s упоминается только как команда replace, например s/pattern/replacement/. Здесь не так.

Часть ^password: "(.*)"$ выглядит как Regex для выделения secret, но она не ограничена.

Я могу понять конечную часть, где распечатывается обратная ссылка \1, но опять же, что там делают запятые?

Обратите внимание, что меня не интересует более простая альтернатива этому примеру sed. Это будет только частью более крупного bash script, который будет включать в себя еще несколько парсинга sed в файле .htaccess, поэтому я действительно хотел бы изучить синтаксис, даже если он неясен.

Спасибо за вашу помощь!

2 ответа

Вот команда sed:

sed -En '/^password: / s,^password: "(.*)"$,\1,p'
  • Запятые используются как разделитель регулярных выражений, он вполне может быть другим разделителем вроде #:

    sed -En '/^password: / s#^password: "(.*)"$#\1#p'`
  • /^password: / находит строку ввода, начинающуюся с password:

  • s#^password: "(.*)"$#\1#p находит и фиксирует строку с двойными кавычками после password: и заменяет всю строку на захваченную строку \1 (так что все, что остается - это пароль)


Сначала команда извлекает пароли из файла (или потока) и печатает их в stdout.

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

В вашем случае

/^password: /

является регулярным выражением, говоря, что команда:

s,^password: "(.*)"$,\1,p

должен выполняться для всех строк, похожих на password: "secret". Команда заменяет эти строки самим паролем при подавлении внешних линий.

Команда substitute может выглядеть необычно, но вы можете выбрать разделитель в команде sed, это не ограничивается /. В этом случае был выбран ,.

licensed under cc by-sa 3.0 with attribution.