在同一行上的两个搜索模式之间提取值

Raz*_*aza 6 sed text-processing

我在文件 Output.dat 中有以下内容。我需要提取价值之间dn: uid=,ou=

 dn: uid=user1,ou=Active,ou=Member,dc=domain,dc=org
 dn: uid=user2@abc.com,ou=Active,ou=Member,dc=domain,dc=org
 dn: uid=usertest,ou=Active,ou=Member,dc=domain,dc=org
 dn: uid=abc1,ou=Active,ou=Member,dc=domain,dc=org
Run Code Online (Sandbox Code Playgroud)

ste*_*ver 12

如果您有一个-P支持PCRE ( )的 GNU grep 版本,那么假设您的意思是第一次出现,ou

grep -oP '(?<=dn: uid=).+?(?=,ou=)' file
Run Code Online (Sandbox Code Playgroud)

如果您想匹配到第二个, ,ou您可以删除非贪婪?修饰符

grep -oP '(?<=dn: uid=).+(?=,ou=)' file
Run Code Online (Sandbox Code Playgroud)

括号中的表达式是零长度断言(又名lookarounds),这意味着它们构成匹配的一部分,但不作为结果的一部分返回。你可以在 perl 中做同样的事情,例如

perl -ne 'print "$1\n" if /(?<=dn: uid=)(.+?)(?=,ou=)/' file 
Run Code Online (Sandbox Code Playgroud)

可以在 sed 中做类似的事情,使用常规(非零长度)分组,例如(对于 GNU sed - 其他品种可能需要额外的转义)

sed -rn 's/(.*dn: uid=)([^,]+)(,ou=.*)/\2/p' file
Run Code Online (Sandbox Code Playgroud)

或稍微简化

sed -rn 's/.*dn: uid=([^,]+),ou=.*/\1/p' file
Run Code Online (Sandbox Code Playgroud)

请注意,[^,]这里有点小技巧,因为 sed 没有真正的非贪婪匹配选项。


事后思考:虽然这不完全是您所要求的,但看起来您真正想要做的是name=value从文件中读取逗号分隔的对,然后进一步从其名称中拆分第一个字段的值。您可以通过多种方式实现这一目标 - 包括

awk -F, '{sub(".*=","",$1); print $1}' file
Run Code Online (Sandbox Code Playgroud)

或纯 bash 解决方案,例如

while IFS=, read -r a b c d; do printf '%s\n' "${a#*=}"; done < file 
Run Code Online (Sandbox Code Playgroud)