Powershell:从 LDIF 文件中提取模式之间的值
Powershell: Extract value between pattern from a LDIF file
我正在研究正则表达式,我的任务是编写一个脚本来提取 LDIF 上搜索模式之间的特定文本,我 运行 遇到了一些问题。我们从中获得的 LDIF 是 OpenLDAP 格式,因此我们拥有的文件是
dn: cn=user1,ou=department,o=company,c=root
changetype: add
givenName: Givenname1
sn: SN1
Country: Cn1
userCertificate;binary:: lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3
City: City1
dn: cn=user3,ou=department3,o=company,c=root
changetype: add
givenName: Givenname3
sn: SN3
customdn: cn=user3,ou=department3,o=company,c=root
userCertificate;binary:: lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3
Country: Cn3
City: City3
dn: cn=user2,ou=department,o=company,c=root
changetype: add
givenName: Givenname2
sn: SN2
customdn: cn=user2,ou=department,o=company,c=root
userCertificate;binary:: lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3
Country: Cn1
City: City1
文件行由换行符 (CRLF) 分隔。因此,我尝试使用以下模式仅为 User3 提取文本,这似乎给我空白文件。
$RegexPattern = "`r`ndn: cn=User3(.*?)`r`n`r`n"
$result = [regex]::match($inputfile,$RegexPattern).Groups[1].Value
如果我将捕获模式从更改为 (.*),我会在第一次匹配后获取所有文本。很确定我遗漏了一些东西,但就是看不到我遗漏了什么。有好心人帮忙吗?
编辑:也添加了一些关于自定义 DN 的附加信息。在 dn: 的搜索字符串中包含 CRLF 的原因是因为用户对象上还有一个自定义 DN,它是用于向后兼容的 dn 属性的副本。我已经用这个属性更新了上面的示例 LDIF 条目。
编辑 2:Wiktor 的正则表达式几乎可以工作,直到代码偶然发现 userCertificate 属性,其中多个属性仅用 LF 分割,而不是在其他地方看到的 CR+LF。
首先,确保将整个文件读入变量:
$inputfile = Get-Content .\input.ldif -Raw
然后,你需要一个像
这样的正则表达式
$RegexPattern = '(?mi)^dn: cn=User3[^\r\n]*(?:\r?\n[^\r\n]+)*'
$result = [regex]::match($inputfile,$RegexPattern).Value
详情
(?mi)
- 不区分大小写的匹配开启并且多行行为也开启
^
- 行首
dn: cn=User3
- 文字文本
[^\r\n]*
- 除了 CR 和 LF 之外的 0+ 个字符
(?:\r?\n[^\r\n]+)*
- CRLF/LF 出现 0+ 次,然后是 CR 和 LF 以外的 1+ 个字符(因此,上述字符串下方的任何非空行)。
另一种方法是将文件作为单个字符串读取,分成 2 个(或更多)换行符并使用 Where-Object
子句来获取以 dn: cn=user3
.[=14= 开头的文本块]
(Get-Content -Path 'D:\Test\openLDAP.ldif' -Raw) -split '(\r?\n){2,}' |
Where-Object { $_.Trim() -match "^dn: cn=user3" }
结果:
dn: cn=user3,ou=department3,o=company,c=root
changetype: add
givenName: Givenname3
sn: SN3
Country: Cn3
City: City3
我正在研究正则表达式,我的任务是编写一个脚本来提取 LDIF 上搜索模式之间的特定文本,我 运行 遇到了一些问题。我们从中获得的 LDIF 是 OpenLDAP 格式,因此我们拥有的文件是
dn: cn=user1,ou=department,o=company,c=root
changetype: add
givenName: Givenname1
sn: SN1
Country: Cn1
userCertificate;binary:: lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3
City: City1
dn: cn=user3,ou=department3,o=company,c=root
changetype: add
givenName: Givenname3
sn: SN3
customdn: cn=user3,ou=department3,o=company,c=root
userCertificate;binary:: lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3
Country: Cn3
City: City3
dn: cn=user2,ou=department,o=company,c=root
changetype: add
givenName: Givenname2
sn: SN2
customdn: cn=user2,ou=department,o=company,c=root
userCertificate;binary:: lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3lowhjsefnasdvonidfb8943th54ebghyLHFUn9894y9bKalkbjsf
89ehgvpnoLNGPOVNnl;aiorgpnsg;n\vbubGB*gpbeoabgpiobrgaragop08hgnaoergn9r0agnh
U0hBMjU2MB4XDTE5MDYwNTA3
Country: Cn1
City: City1
文件行由换行符 (CRLF) 分隔。因此,我尝试使用以下模式仅为 User3 提取文本,这似乎给我空白文件。
$RegexPattern = "`r`ndn: cn=User3(.*?)`r`n`r`n"
$result = [regex]::match($inputfile,$RegexPattern).Groups[1].Value
如果我将捕获模式从更改为 (.*),我会在第一次匹配后获取所有文本。很确定我遗漏了一些东西,但就是看不到我遗漏了什么。有好心人帮忙吗?
编辑:也添加了一些关于自定义 DN 的附加信息。在 dn: 的搜索字符串中包含 CRLF 的原因是因为用户对象上还有一个自定义 DN,它是用于向后兼容的 dn 属性的副本。我已经用这个属性更新了上面的示例 LDIF 条目。 编辑 2:Wiktor 的正则表达式几乎可以工作,直到代码偶然发现 userCertificate 属性,其中多个属性仅用 LF 分割,而不是在其他地方看到的 CR+LF。
首先,确保将整个文件读入变量:
$inputfile = Get-Content .\input.ldif -Raw
然后,你需要一个像
这样的正则表达式$RegexPattern = '(?mi)^dn: cn=User3[^\r\n]*(?:\r?\n[^\r\n]+)*'
$result = [regex]::match($inputfile,$RegexPattern).Value
详情
(?mi)
- 不区分大小写的匹配开启并且多行行为也开启^
- 行首dn: cn=User3
- 文字文本[^\r\n]*
- 除了 CR 和 LF 之外的 0+ 个字符
(?:\r?\n[^\r\n]+)*
- CRLF/LF 出现 0+ 次,然后是 CR 和 LF 以外的 1+ 个字符(因此,上述字符串下方的任何非空行)。
另一种方法是将文件作为单个字符串读取,分成 2 个(或更多)换行符并使用 Where-Object
子句来获取以 dn: cn=user3
.[=14= 开头的文本块]
(Get-Content -Path 'D:\Test\openLDAP.ldif' -Raw) -split '(\r?\n){2,}' |
Where-Object { $_.Trim() -match "^dn: cn=user3" }
结果:
dn: cn=user3,ou=department3,o=company,c=root changetype: add givenName: Givenname3 sn: SN3 Country: Cn3 City: City3