1

Я пытаюсь использовать 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, он ничего не возвращает. Что-нибудь очевидное, что я делаю неправильно?

PowerShell:

$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 ответ1

0

Если вы посмотрите на следующий вопрос, вы увидите способ заставить 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;
}

Обратите внимание, что в примере не используется однострочный модификатор, потому что он не нужен. Он читает файл и объединяет строки, не используя ничего в качестве разделителя.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .