Выберите несколько подстрок из многострочной строки

Я пытаюсь создать сценарий PowerShell для выбора отдельных строк из больших файлов журнала. С помощью Select-StringЯ собрал данные до нужных мне строк в многострочной строке. Теперь я бы хотел еще больше помассировать его, чтобы он возвращал только идентификаторы из этих строк в виде одной строки, разделенной запятыми.

Текущий код:

if (Select-String $SearchFile -Pattern $SearchString -Quiet) {
    Write-Host "Error message found"
    $body += Select-String $SearchFile -Pattern $SearchString -Context 1,0 |
             foreach {$_.Context.DisplayPreContext} | Out-String
    Send-MailMessage (email_info_here) -Body $body
} else {
    Write-Host "No errors found"
}

В настоящее время возвращает следующую строку:

ИНФО | Создание партии для 197988 | 24.03.2016 02:10
ИНФО | Создание партии для 202414 | 24.03.2016 02:10
ИНФО | Создание партии для 173447 | 24.03.2016 02:10

Хотел бы получить вывод в формате:

197988, 202414, 173447

3 ответа

Решение

Замещать Out-String с Where-Object Фильтр, который соответствует числовой части каждой строки результата, извлекает подсписок чисел и присоединяет результат:

$body += (Select-String $SearchFile -Pattern $SearchString -Context 1,0 |
         ForEach-Object { $_.Context.DisplayPreContext } |
         Where-Object { $_ -match 'for (\d+) \|' } |
         ForEach-Object { $matches[1] }) -join ', '

Если Body содержит эти строки, то вам просто нужно разделить и проиндексировать столбец с нашими данными.

$body | ForEach-Object {$psitem.Split()[5]}
197988
202414
173447  

В этом примере мы вызываем ForEach-Object, чтобы создать небольшой блок кода для выполнения в каждой строке. Затем мы называем линию $split() метод разделения на пробелы. Затем мы просто индексировать в пятый столбец, используя $psitem[5],

Предполагая, что вы хотите сохранить строки обратно в $body опять просто добавь $body = в начале линии 1.

Изменить: многострочная строка против массива

В исходном сообщении переменная $body была создана с Out-String как последняя команда в конвейере. Это сделало бы это единственной многострочной строкой. Оставляя вне | Out-String part сделает $body массивом строк. С последним (массивом) легче работать, и это то, что предполагает ответ, приведенный выше, поскольку легко проходить по каждой строке массива с помощью foreach,

Преобразование между ними выполняется следующим образом:

$string = @"
INFO | Creating Batch for 197988 | 03/24/2016 02:10 AM
INFO | Creating Batch for 202414 | 03/24/2016 02:10 AM
INFO | Creating Batch for 173447 | 03/24/2016 02:10 AM
"@

$array = @(
"INFO | Creating Batch for 197988 | 03/24/2016 02:10 AM"
"INFO | Creating Batch for 202414 | 03/24/2016 02:10 AM"
"INFO | Creating Batch for 173447 | 03/24/2016 02:10 AM"
)

$array_from_string = $string -split("`n")
$string_from_array = $array | Out-String

Чтобы ответ работал, вам нужно убедиться, что $body является массивом, иначе вы получите только один идентификационный номер:

$string | Foreach-Object {$psitem.Split()[5]}
197988

Это может быть грязный способ сделать это, но это работает:

#This can also be your variable
$log = gc "C:\[log path here]"

#Remove beginning of string up to ID
$log = $log -replace '(.*?)for ' , ""

#Select first 6 characters since all IDs shown are 6 characters
$logIDs = @()
foreach($line in $log){
    $logIDs += $line.substring(0,6)
}

### At this point $logIDs contains all IDs, now we just need to comma separate them ###

$count = 1
foreach($ID in $logIDs){
    if($count -eq $logIDs.count){
        $result += $ID
    }
    else{
        $result += $ID+", "
        $count++
    }
}

#Here are your results separated by commas
$result

Надеюсь, это поможет, дайте мне знать, если вам нужны какие-либо варианты.

Другие вопросы по тегам