Bash awk/sed从模式之间提取字符串

Bash awk/sed从模式之间提取字符串,bash,awk,sed,grep,pattern-matching,Bash,Awk,Sed,Grep,Pattern Matching,我知道这个问题在stackoverflow上可能有几百种形式,但我似乎找不到一个合适的答案来回答我的问题 我正试图解析Linux机器上的/etc/ldap.conf文件,这样我就可以从(description=和)之间明确地选择描述字段了。: nss\u base\u passwd ou=People,dc=ca,dc=somecompany,dc=com?one?(description=TD\u-FI)(description=TD\u-F6)(description=TD\u-F6)(de

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

我正试图解析Linux机器上的
/etc/ldap.conf
文件,这样我就可以从
(description=
)之间明确地选择描述字段了。

nss\u base\u passwd ou=People,dc=ca,dc=somecompany,dc=com?one?(description=TD\u-FI)(description=TD\u-F6)(description=TD\u-F6)(description=14\u-142)(description=REX5)(description=REX5)(说明=1950)*

我希望将这些内容提取到他们自己的列表中,不重复:

TD_FI
TD_F6
TRI_142
14_142
REX5
1950
(或全部在一行中,并带有适当的分隔符)


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

您可以使用grep和
-p
选项

$ grep '^nss_base_passwd' /etc/ldap.conf | grep -oP '(?<=description\=)[^)]*' | uniq
TD_FI
TD_F6
TRI_142
14_142
REX5
1950
$grep'^nss\u base\u passwd'/etc/ldap.conf | grep-oP'(?尝试以下操作:

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

  • 使用
    bash
    ,如果以
    (或
    \
    &&
    )结束一行,shell知道命令将在下一行继续,因此不需要使用
    \

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

  • 由于
    -o
    将打印整个匹配,因此我们需要提取前缀后的部分,我们使用
    cut
    ,指定一个分隔符
    =
    -f2-
    意味着“所有字段都从第二个字段开始”,如果描述中有
    =
    ,我们需要这个分隔符

  • 非常接近。这是我的改进版本:

    grep '^nss_base_passwd' /etc/ldap.conf | grep -Po '\(description=\K[^)]+' | sort -u
    
    如果只需使用
    \K
    (这实际上是对应零宽度断言的快捷方式),则无需使用语法


    另外,您说过不需要重复项,但是
    uniq
    只会删除重复的相邻行,如果中间有什么东西,它不会删除重复项。这就是为什么我使用
    sort-u

    需要确保这仅限于以“nss\u base\u passwd”开头的行这些都正是我想要的。谢谢大家——你们是救命恩人。@AvinashRaj请看我的答案,它可能会让你们感兴趣。
    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
    
    grep '^nss_base_passwd' /etc/ldap.conf | grep -Po '\(description=\K[^)]+' | sort -u