Regex 使用egrep和awk获取两个模式之间的文本

Regex 使用egrep和awk获取两个模式之间的文本,regex,bash,awk,grep,Regex,Bash,Awk,Grep,我正试图解析一个命令的帮助文件,以获取除命令之外的所有参数 以下是帮助文件中的一些文本: * --digest: Set the digest for fingerprinting (defaults to the digest used when signing the cert). Valid values depends on your openssl and openssl ruby extension version. * --debug: Enable full d

我正试图解析一个命令的帮助文件,以获取除命令之外的所有参数

以下是帮助文件中的一些文本:

* --digest:
  Set the digest for fingerprinting (defaults to the digest used when
  signing the cert). Valid values depends on your openssl and openssl ruby
  extension version.

* --debug:
  Enable full debugging.

* --help:
  Print this help message

* --verbose:
  Enable verbosity.

* --version:
  Print the puppet version number
我只想抓住
--参数
,别的什么都不想

我几乎用这个命令得到了它,但它仍然包括“:”我想排除它:

puppet cert --help | egrep '^* --(.*):$' | awk '{print $2}'
--all:
--allow-dns-alt-names:
--digest:
--debug:
--help:
--verbose:
--version:

为什么
'^*-(.*):$'
包括“:”它不应该匹配
'^*-'
':$”之间的所有内容吗?

提供一个符合POSIX的替代方案(这也解释了OP方法不起作用的原因):


更新:Avinash Raj在一篇评论中指出,
sed
是一个选项,它确实允许使用符合POSIX标准的单一工具解决方案:
sed
允许我们匹配整个感兴趣行,并用捕获组(感兴趣行的一部分)的内容替换它们:

请注意,由于使用
sed
时没有-nonstandard-
-r
/
-E
选项,因此必须使用基本正则表达式,其中
必须转义以充当捕获组定界符。


原始答复:

puppet cert --help | egrep '^\* --.+:$' | awk -F '\\* |:' '{print $2}'
注:

  • ^*
    被替换为
    ^\*
    ,以确保
    *
    作为文本匹配,
    (.*)
    被替换为
    +
    ,因为(a)这里的捕获组无法获得任何信息,(b)可以公平地假设
    后面至少有一个字母

  • -F'\*\\:'
    使用文本
    *
    作为字段分隔符,这确保只打印
    --…
    标记(第二个字段)

它不应该匹配
^*-
之间的所有内容:$

事实上,没有。您正在捕获一个组,但它不会只打印组。我建议使用
-P
标志来使用Perl正则表达式,并环顾四周。在您的情况下,这可能就足够了:

$ cert --help | grep -Po '^\* \K--\w+'
注意,我还使用了
-o
选项,仅打印匹配的内容,而不是整行内容。这消除了awk的使用


基于您最初的想法和更多环顾四周的内容,提供更完整的路线:

$ cert --help | grep -Po '^\* \K--.*(?=:)'

编辑:正如mklement0在评论和精细回答中指出的,这需要GNU grep。不过,您也可以对Perl本身执行同样的操作,Perl很可能已经安装在您的系统中

$ cert --help | perl -nle 'print $1 if /^\* (--\w+)/'
这就像循环中的一行代码。由
-nle
自动生成
-n
表示输入外观,
-l
表示自动换行,而
-e
表示代码行

如果Perl代码行与正则表达式匹配,则该行将打印第一个捕获的组。因此,它也结合了原始解决方案中的想法


要获得与POSIX兼容的完整答案,请查看本页此处。

做得好,但请注意,使用
-p
需要GNU
grep
@mklement0 true,我将添加一个注释,可能还有一个Perl版本本身。谢谢@您的系统中可能没有red888。请稍候,我将使用更安全的Perl版本进行编辑<代码>-P
用于perl正则表达式,用于查找
-o
是只打印匹配的内容,正如我在answer@red888:无需重复的原因可能是没有在
^*
-try
^\*
@mklement0中转义原本的
*
-是的,这就是问题所在。对不起,我没注意到。感谢您指出这一点。
sed-nr的/^\*|::.*//p'
很久以前,我们有一个非常好的工具来查找文件,它被命名为
find
,然后GNU的人用
grep
来添加文件查找参数。很久以前,我们有一个非常好的工具,用于
ed
iting
s
treams(包括选择与regexp匹配的字符串),它被命名为
sed
,然后GNU的家伙们用
grep
来添加流编辑参数。我迫不及待地想让他们添加对输出进行排序等功能-很快我们就不需要任何其他命令了,只需要全能的
grep
。希望那些改变了
grep
的GNU成员在使用它之前读过一本UNIX书籍。你也可以使用sed。谢谢你的参考资料。我现在添加了一个Perl版本。考虑到POSIX法规遵从性,它现在就适合了,因为需要Perl:-D也感谢您在这个原始工具解决方案中的出色解释。已经upvoted@sidyll:我的荣幸;Perl解决方案也做得不错。(我不确定您对Perl和POSIX说了什么,但如果您认为Perl是POSIX的一部分:我不认为是;但是,Perl在主要的非GNU实用程序平台OSX上是可用的)。有疑问,是真的。我相信我在这个网站的某个地方读过,但我找不到。你是对的,我认为它确实不包括在内。虽然像你说的那样大部分时间都可以用。
$ cert --help | perl -nle 'print $1 if /^\* (--\w+)/'