我正在尝试使用 powershell 来匹配下面的用户名和用户状态:
Internal user ID: 1 Login name: ADMINISTRATOR
Last login:
Last update user ID: 2 Date and time created: Tue Oct-25-2016 10:59:31
User status: ENABLED Reason for last status change: 0
使用我的正则表达式生成器,我可以进行以下工作:
Login name:\s+(\w+)\n.*\n.*\nUser status:\s+(ENABLED|DISABLED)
但当我在 select-string 中使用它时,它没有返回任何内容。我做错了什么吗?
电源外壳:
$as = select-string "c:\users\ssfors\desktop\audit\user.rep" -pattern "Login name:\s+(\w+)\n.*\n.*\nUser status:\s+(ENABLED|DISABLED)"
foreach ($a in $as) {
echo $a.matches.groups[1].Value
}
答案1
如果你看一下下面的问题,你会看到一种让 PowerShell/Select-String
使用单行模式的方法:多行正则表达式匹配配置块
您面临的问题是,默认情况下,通常每行输入都应用一个 RegEx。因此,您的 RegEx 只对包含Internal user ID
和的第一行起作用Login name
。
您需要做的是从输入中删除换行符或指示Select-String
使用单行模式。在这两种情况下,您都应该调整 RegEx 以不使用它,\n
因为不需要它。您可以这样做:
Login name:\s+(\w+)\s+.*?User status:\s+(ENABLED|DISABLED)
此后,您要么需要通过例如运行来调整输入-replace '`n'
(还请注意,您应该`n
在 PowerShell 中使用),要么可以像上面的问题中所述那样在输入上使用修饰符。 在这种情况下,您的 RegEx 将更改为:
(?s)Login name:\s+(\w+)\s+.*?User status:\s+(ENABLED|DISABLED)
即使完成了所有这些操作,您仍然还没有完成,Select-String
如果您提供,实际上会逐行返回输入-Path
,因此最好事先一次读取整个文件。
例如:
$fileContent = (Get-Content c:\users\ssfors\desktop\audit\user.rep) -join ''
$results = $fileContent | Select-String -pattern "Login name:\s+(\w+)\s+.*?User status:\s+(ENABLED|DISABLED)" -AllMatches
foreach($match in $results.Matches){
foreach($group in $match.Groups){
echo $group.Value
}
}
if($results.Matches.Count -eq 1 -and $results.Matches[0].Groups.Count -eq 3){
echo "User Name:", $results.Matches[0].Groups[1].Value;
echo "Status:", $results.Matches[0].Groups[2].Value;
}
请注意,该示例不使用单行修饰符,因为没有必要。它读取文件并使用无分隔符连接各行。