【问题标题】:awk/sed extract string from between patternsawk/sed 从模式之间提取字符串
【发布时间】:2014-06-19 17:53:09
【问题描述】:

我知道在 stackoverflow 上可能已经有几百种形式的这个问题被问到了,但我似乎找不到合适的答案来回答我的问题。

我正在尝试解析 Linux 机器上的 /etc/ldap.conf 文件,以便我可以从 (description=) 之间专门挑选出描述字段:

*-bash-3.2$ grep '^nss_base_passwd' /etc/ldap.conf

nss_base_passwd ou=People,dc=ca,dc=somecompany,dc=com?one?|(description=<strong>TD_FI</strong>)(description=<strong>TD_F6</strong>)(description=<strong>TD_F6</strong>)(description=<strong>TRI_142</strong>)(description=<strong>14_142</strong>)(description=<strong>REX5</strong>)(description=<strong>REX5</strong>)(description=<strong>1950</strong>)*

我希望将它们提取到他们自己的列表中,并且没有重复:

TD_FI
TD_F6
TRI_142
14_142
REX5
1950

(或全部在一行中,并带有适当的分隔符)

我已经使用sed 玩了几个小时,但无法让它工作 - 我不完全确定如何使用全局选项。

【问题讨论】:

    标签: bash awk sed grep pattern-matching


    【解决方案1】:

    您可以将 grep 与 -P 选项一起使用,

    $ grep '^nss_base_passwd' /etc/ldap.conf | grep -oP '(?<=description\=)[^)]*' | uniq
    TD_FI
    TD_F6
    TRI_142
    14_142
    REX5
    1950
    

    说明:

    在 grep 中使用正向向后查找来打印紧跟在 description= 之后的所有字符,直到下一个 ) 括号。 uniq 命令用于删除重复项。

    【讨论】:

    • 需要确保这仅限于以“nss_base_passwd”开头的行
    • 这些都完全符合我的要求。谢谢大家 - 你是救生员。
    • @AvinashRaj 请看我的回答,你可能会感兴趣。
    【解决方案2】:
    perl -nE 'say join(",", /description=\K([^)]+)/g) if /^nss_base_passwd/' /etc/ldap.conf
    
    TD_FI,TD_F6,TD_F6,TRI_142,14_142,REX5,REX5,1950
    

    【讨论】:

      【解决方案3】:

      试试这个:

      grep '^nss_base_passwd' /etc/ldap.conf |
      grep -oE '[(]description=[^)]*' | sort -u |
      cut -f2- -d=
      

      解释:

      1. 使用bash,如果你以|(或||&amp;&amp;)结束一行,shell知道命令在下一行继续,所以你不需要使用\

      2. 第二个grep 使用-o 标志来指示应该打印出匹配的表达式,每行一个。它还使用-E 标志来指示该模式是“扩展”(即正常)正则表达式。

      3. 由于-o 将打印整个匹配项,我们需要提取前缀后面的部分,为此我们使用cut,指定分隔符=-f2- 表示“以第二个字段开头的所有字段”,如果描述中有=,我们需要它。

      【讨论】:

        【解决方案4】:

        Avinash's answer 非常接近。这是我的改进版:

        grep '^nss_base_passwd' /etc/ldap.conf | grep -Po '\(description=\K[^)]+' | sort -u
        

        当您可以简单地使用\K(这实际上是相应的零宽度断言的快捷方式)时,无需使用lookaround 语法。

        另外,你说你不想重复,但uniq 只会删除重复的相邻行,如果中间有东西,它不会删除重复。这就是我改用sort -u 的原因。

        【讨论】:

          猜你喜欢
          • 2016-04-26
          • 2011-09-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多