2014-11-12 1 views
1

У меня есть команда оболочки Я хотел бы извлечь данные из Powershell. Данные, которые мне нужны, всегда будут находиться между двумя ключевыми словами, и количество захваченных строк может измениться.Извлечь несколько строк текста между двумя ключевыми словами из команды оболочки в powershell

Выход может выглядеть примерно так.

Sites: 
System1: 
RPAs: OK 
Volumes: 
    WARNING: Storage group DR_UCS_01-08 contains both replicated and unreplicated volumes. ; CS_TX 
    WARNING: Storage group DR_UCS_21-28 contains both replicated and unreplicated volumes. ; CS_TX 
    WARNING: Storage group DR_UCS_31-38 contains both replicated and unreplicated volumes. ; CS_TX 
Splitters: OK 
System2: 
RPAs: OK 
Volumes: 
    WARNING: Storage group MA_UCS_1 contains both replicated and unreplicated volumes. ; CS_MA 
    WARNING: Storage group MA_UCS_2 contains both replicated and unreplicated volumes. ; CS_MA 
    WARNING: Storage group MA_UCS_3 contains both replicated and unreplicated volumes. ; CS_MA 
Splitters: OK 
WAN: OK 
System: OK 

Я хотел бы, чтобы захватить и сохранить в переменную (или текстовый файл, если проще?) Часть этих данных для повторного использования в сценарии. Например, я хотел бы, чтобы захватить все между System1: и System2: который будет производить:

RPAs: OK 
Volumes: 
    WARNING: Storage group DR_UCS_01-08 contains both replicated and unreplicated volumes. ; CS_MA 
    WARNING: Storage group DR_UCS_21-28 contains both replicated and unreplicated volumes. ; CS_MA 
    WARNING: Storage group DR_UCS_31-38 contains both replicated and unreplicated volumes. ; CS_MA 
Splitters: OK 

Я Мессинг с различными комбинациями регулярных выражений без успеха. У меня был некоторый умеренный успех с этим кодом, но он, похоже, не способен обрабатывать строки предупреждения, и я также не могу заставить Out-File работать с ним, но только Write-Host, который не помогает меня много.

$RP = plink -l User -pw Password 192.168.1.100 "get_system_status summary=no" #extract from 

$script = $RP 

$in = $false 

$script | %{ 
if ($_.Contains("System1")) 
    { $in = $true } 
elseif ($_.Contains("System2")) 
    { $in = $false; } 
elseif ($in) 
    { Write-Host $_ } 
} 

В идеале, я хотел бы иметь возможность использовать этот скрипт и использовать его для анализа данных из любой команды оболочки. В настоящее время я потерян и почти готов отказаться от этого.

ответ

0

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

$text = 
(@' 
Sites: 
System1: 
RPAs: OK 
Volumes: 
    WARNING: Storage group DR_UCS_01-08 contains both replicated and unreplicated volumes. ; CS_TX 
    WARNING: Storage group DR_UCS_21-28 contains both replicated and unreplicated volumes. ; CS_TX 
    WARNING: Storage group DR_UCS_31-38 contains both replicated and unreplicated volumes. ; CS_TX 
Splitters: OK 
System2: 
RPAs: OK 
Volumes: 
    WARNING: Storage group MA_UCS_1 contains both replicated and unreplicated volumes. ; CS_MA 
    WARNING: Storage group MA_UCS_2 contains both replicated and unreplicated volumes. ; CS_MA 
    WARNING: Storage group MA_UCS_3 contains both replicated and unreplicated volumes. ; CS_MA 
Splitters: OK 
WAN: OK 
System: OK 
'@).split("`n") | 
foreach {$_.trim()} 

$text -join "`n" -split '(?ms)(?=^System\d+:\s*)' -match '^System\d+:' 

System1: 
RPAs: OK 
Volumes: 
WARNING: Storage group DR_UCS_01-08 contains both replicated and unreplicated volumes. ; CS_TX 
WARNING: Storage group DR_UCS_21-28 contains both replicated and unreplicated volumes. ; CS_TX 
WARNING: Storage group DR_UCS_31-38 contains both replicated and unreplicated volumes. ; CS_TX 
Splitters: OK 

System2: 
RPAs: OK 
Volumes: 
WARNING: Storage group MA_UCS_1 contains both replicated and unreplicated volumes. ; CS_MA 
WARNING: Storage group MA_UCS_2 contains both replicated and unreplicated volumes. ; CS_MA 
WARNING: Storage group MA_UCS_3 contains both replicated and unreplicated volumes. ; CS_MA 
Splitters: OK 
WAN: OK 
System: OK 

Edit: более общее решение, чтобы просто захватить выход между двумя конкретными ключевыми словами:

$regex = '(?ms)System1:(.+?)System2:' 

$text = $text -join "`n" 

$OutputText = 
[regex]::Matches($text,$regex) | 
foreach {$_.groups[1].value -split } 
+0

Возможно, я не понимаю ваш ответ. Предполагая, что мой вывод оболочки хранится в $ text, вы можете сказать мне код, чтобы извлекать данные между двумя ключевыми словами. Это не всегда будет system1 и system2 – RichT

+0

Хорошо, я думаю, что неверно понял вопрос. Обновлен ответ с более общим решением. – mjolinor

+0

Это похоже на то, что я ищу! Можно ли сохранить этот вывод в новую строку, например $ output. – RichT

0

Попробуйте это регулярное выражение:

$result = ($text | Select-String 'System1:\s*\r\n((.*\r\n)*)\s*System2:' -AllMatches) 
$result.Matches[0].Groups[1].Value 

Где $ текст ваш оригинальный вход. Обратите внимание, что вам, возможно, придется отрегулировать окончание строк от \ r \ n до \ n в зависимости от вашего ввода. У вас также может быть несколько совпадений, я не уверен в вашем примере.

Регулярное выражение начинает сопоставление с System1:\s*\r\n, которое представляет собой System1, за которым следует любое количество пробелов, за которым следует новая строка. Он заканчивает матч буквами System2:. Внутренняя средняя, ​​.*\r\n, соответствует всем символам, за которыми следует новая строка. Внешняя средняя (.*\r\n)* говорит, что повторяет этот шаблон. Наконец, эта конструкция сгруппирована, ((.*\r\n)*), так что все соответствующие линии могут быть извлечены в результате.

+0

Это возвращает ошибку: 'code'Cannot index в нулевой массив. В строке: 6 символов: 1 + $ result.Matches [0] .Groups [1] .Value + ~~~~~~~~~~~~~~~ ~~~~~~~~~~ + CategoryInfo: InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId: NullArray) – RichT

+0

Вы подтвердили свой формат новой строки? Осмотреть $ result.Matches и $ result.Matches [0]. Я проверил его с вашим образцом. – Swoogan

+0

Я попытался переключить \ r \ n на \ n, но все равно получаю ту же ошибку. – RichT

Смежные вопросы