2014-01-30 85 views
4

我找到了一个解决方案,用于从Mac OS X钥匙串项目中提取密码。它使用sedsecurity命令获取密码:了解sed示例

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

的代码是由“sr105”评论here|之前的部分评估为password: "secret"。我试图弄清楚sed命令是如何工作的。这里有一些想法:

我明白国旗-En,但在这个例子中逗号是什么?在sed文档中,它表示逗号分隔地址范围,但有3个逗号。

第一个'地址'/^password: /有尾部s;在文档s中仅提到了替换命令,如s/pattern/replacement/。这里不是这种情况。

^password: "(.*)"$部分看起来像正则表达式隔离secret,但它没有分隔。

我可以理解打印出后引用\1的最后部分,但是再次,那里的逗号是什么?

请注意,我对这个sed示例的替代方法不感兴趣。这只会是一个更大的bash脚本的一部分,它将在.htaccess文件中包含一些更多的sed解析,因此我很想知道它的语法,即使它是晦涩难懂。

感谢您的帮助!

+1

逗号是随机的分隔符,它们可能是别的。 ^,^密码:“(。*)”$,\ 1,p == s/^密码:“(。*)”$/\ 1/p' – Wrikken

+0

刚才我刚才意识到。我应该回答我自己的问题吗? – Timm

+0

现在不是已经有2个人为你做了这个工作,对它进行了更详细的解释;) – Wrikken

回答

5

这里是sed命令:

sed -En '/^password:/s,^password: "(.*)"$,\1,p' 
  • 逗号被用作正则表达式定界符它可以很好地像#另一个分隔符:

    sed -En '/^password:/s#^password: "(.*)"$#\1#p'` 
    
  • /^password: /发现一个启动输入线与password:

  • s#^password: "(.*)"$#\1#p查找并password:后捕获双引号字符串和替换与所捕获的字符串\1整行(因此,所有剩下的就是口令)从一个文件(或流),并打印
+0

啊,我明白了。这个人试图避免'/',因为它可能在密码中。 – Timm

+1

是的,这将是原因。 sed允许任何字符(包括控制字符)作为分隔符。 – anubhava

+1

是否有任何理由认为逗号不在密码中,但是正斜杠会是? – Floris

0

首先,命令提取密码他们来标准输出。

虽然“正常”可能会在文件的所有行上执行sed命令,sed会提供指定一个正则表达式模式,该模式描述应将下列命令应用于哪条线。

在你的情况

/^password:/

是一个正则表达式,说命令:

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

应该看起来像password: "secret"所有行得到执行。该命令将这些行替换为密码本身,同时抑制外部行。

替换命令可能看起来并不常见,但您可以在sed命令中选择分隔符,但不限于/。在这种情况下,选择了,