我在文件 Output.dat 中有以下内容。我需要提取dn: uid=
和之间的值,ou=
dn: uid=user1,ou=Active,ou=Member,dc=domain,dc=org
dn: [email protected],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
- 我尝试使用
它返回完整的行而不是值。sed -e '/dn: uid=/,/,ou=/p' output.dat but
- 当尝试使用时
然后得到以下错误:sed -e '/dn: uid=/,/,ou=/\1/p' output.dat
sed: -e expression #1, char 18: unknown command: `\'
答案1
如果您有一个支持 PCRE ( ) 的 GNU grep 版本-P
,那么假设您的意思是第一的的发生,ou
grep -oP '(?<=dn: uid=).+?(?=,ou=)' file
如果你想匹配第二 ,ou
您可以删除非贪婪?
修饰符
grep -oP '(?<=dn: uid=).+(?=,ou=)' file
括号中的表达式是零长度断言(又名环顾四周) 意味着它们构成匹配的一部分,但不会作为结果的一部分返回。你可以在 perl 中本地做同样的事情,例如
perl -ne 'print "$1\n" if /(?<=dn: uid=)(.+?)(?=,ou=)/' file
做某事是可能的相似的在 sed 中,使用常规(非零长度)分组,例如(对于 GNU sed - 其他变体可能需要额外转义)
sed -rn 's/(.*dn: uid=)([^,]+)(,ou=.*)/\2/p' file
或稍微简化
sed -rn 's/.*dn: uid=([^,]+),ou=.*/\1/p' file
请注意,[^,]
这里有点 hack,因为 sed 没有真正的非贪婪匹配选项。
事后的想法:虽然这并不完全符合您的要求,但看起来您真正想要做的是name=value
从文件中读取逗号分隔的对,然后进一步将第一个字段的值与其名称分开。您可以通过多种方式实现这一目标 - 包括
awk -F, '{sub(".*=","",$1); print $1}' file
或纯 bash 解决方案,例如
while IFS=, read -r a b c d; do printf '%s\n' "${a#*=}"; done < file
答案2
这对于 awk 来说是一个很好的工作。您可以拆分字符串,而不是尝试使用正则表达式。这是一个解决方案:
$ awk -F= '{ split($2,arr,","); print arr[1] }' test.txt
user1
[email protected]
usertest
abc1
答案3
和sed
:
sed 's/[^=]*=\([^,]\+\),.*/\1/' file
这假设uid=
将在该行上第一次出现=
,并且假设您想在,ou=
该行的第一个实例处停止。
解释
这将查找任意数量的非=
字符 ( [^=]*
) 后跟=
then 匹配,并保存尽可能多的非逗号 ( \([^,]\+\)
) 后跟逗号以及该行的其余部分 ( ,.*
)。这意味着它将用它在该行=
第一个逗号之后找到的任何非逗号字符替换第一个逗号之前和之后的所有内容。=
答案4
还有一些选择,按长度顺序排列:
grep
带有 PCRE 的GNUgrep -oP 'uid=\K[^,]+' file
丢弃
\K
与该点匹配的所有内容,与-o
开关结合将导致仅打印后的grep
最长非字符。,
uid=
awk
awk -F'[=,]' '{print $2}' file
-F'[=,]
将字段分隔符设置为或者=
第二,
个字段是用户名。sed
sed -r 's/.{8}([^,]*).*/\1/' file
这将匹配前 7 个字符 (
.{7}
)=
,捕获最长的非,
as部分\1
并将整行替换为\1
。perl
perl -pe 's/.+?=([^,]+).*/$1/' file
意思
-pe
是“在应用 -e 给出的脚本后打印每一行”。是s///
替换运算符,正则表达式查找第一个(.+?
,?
使其匹配最短的可能字符串) ,然后捕获此后=
最长的非字符段。,
替换s///
与捕获的内容(括号内的内容)匹配的内容。cut
cut -d'=' -f 2 file | cut -d ',' -f 1
将
-d
分隔符设置为,=
因此第二个 (-f 2
) 字段为username,ou
。第二个cut
用作,
分隔符并单独打印用户名。