简体   繁体   中英

Understanding a sed example

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!

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 )

First, the command extracts passwords from a file (or stream) and prints them to stdout.

While you "normally" might execute a sed command on all lines of a file, sed offers to specify a regex pattern which describes which lines the following command should get applied to.

In your case

/^password: /

is a regex, saying that the command:

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

should get executed for all lines looking like password: "secret" . The command substitutes those lines with the password itself while suppressing the outer lines.

The substitute command might look uncommon but you can choose the delimiter in an sed command, it is not limited to / . In this case , was chosen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM