Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding a sed example

Tags:

regex

bash

sed

I found a solution for extracting the password from a Mac OS X Keychain item. It uses sed to get the password from the security command:

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

The code is here in a comment by 'sr105'. The part before the | evaluates to password: "secret". I'm trying to figure out exactly how the sed command works. Here are some thoughts:

I understand the flags -En, but what are the commas doing in this example? In the sed docs it says a comma separates an address range, but there's 3 commas.

The first 'address' /^password: / has a trailing s; in the docs s is only mentioned as the replace command like s/pattern/replacement/. Not the case here.

The ^password: "(.*)"$ part looks like the Regex for isolating secret, but it's not delimited.

I can understand the end part where the back-reference \1 is printed out, but again, what are the commas doing there??

Note that I'm not interested in an easier alternative to this sed example. This will only be part of a larger bash script which will include some more sed parsing in an .htaccess file, so I'd really like to learn the syntax even if it is obscure.

Thanks for your help!

like image 902
Timm Avatar asked Jan 30 '14 19:01

Timm


1 Answers

Here is sed command:

sed -En '/^password: / s,^password: "(.*)"$,\1,p'
  • Commas are used as regex delimiter it can very well be another delimiter like #:

    sed -En '/^password: / s#^password: "(.*)"$#\1#p'`
    
  • /^password: / finds an input line that starts with password:

  • s#^password: "(.*)"$#\1#p finds and captures double-quoted string after password: and replaces the entire line with the captured string \1 ( so all that remains is the password )
like image 73
anubhava Avatar answered Sep 19 '22 19:09

anubhava