2016-05-12 2 views
2

Я получил следующие данные в переменный $ из (типа Object []):PowerShell: получить данные между двумя строками

Success... 
Go! 
0:#217> trace && .quit 
    0x000 Subline   : _OK 
    0x008 Timed  : NO 
    0x016 Check  : _OK 
    0x022 Post  : 
    0x030 Offset   : None 
    0x038 Hint  : False 
    0x050 NextHint : False 
quit: 

Мне нужно извлечь текст между строкой 0: # 217> следом & & .quit и бросить курить: я писал:

[Regex]::Match($out, "(?<=.quit').+?(?=quit:)").Value 

Но это экстракты необходимые данные в линию (тип String), а не столбец (Object []). Как это исправить?

P.S. Я решил проблему сам, как следует

([Regex]'(?is)(?:(?<=\.quit).+(?=quit:))').Match(($out -join "`n")).Value 

Но, может быть, есть более совершенный способ сделать это?

+0

Когда я запустить регулярное выражение для 'String []', которые пришли из 'Get-Content', я не получаю никаких результатов. Используя ответ @ jisaak на 'String []', я получаю результаты, а вы этого не делаете. Как вы создали '$ out'? – TessellatingHeckler

ответ

1

Проблема решена

([Regex]'\s+0x([^q]+)').Match(($out -join "`n")).Value 
0

Просто используйте функцию -split создать String[] вашего результата:

$result = ([regex]::Match($a, '\.quit(.*)quit:').Groups[1].value) -split [System.Environment]::NewLine 
+0

Не работает. У меня такой же результат. – kate

+0

Попробуйте разбить, используя 'n –

0

[Edit: это будет работать, если $out является String[], например, от $out = Get-Content results.txt, из ваших других комментариев у вас может быть что-то другое].

В качестве общего подхода используйте флаг true/false, который выбирает, разрешены ли строки или нет, и когда вы видите первую строку, установите флаг, и когда вы увидите последнюю нужную строку, измените флаг ,

$middle = foreach ($line in $out) { 
    if ($line -match '^quit') { $allow = $false } 
    if ($allow) { write-output $line } 
    if ($line -match '0:#217>') { $allow = $true } 
} 

Порядок проведения испытаний определяет, появляются ли начальные или конечные линии в результатах или нет.

Это может быть сокращено на консоли для ввода, в чем-то вроде:

# loop # end line clears flag  # print?  # start line sets flag 
$out |% { if($_ -match '^quit'){$f=0}; if ($f){$_}; if ($_ -match '0:#217>'){$f=1} } 
+0

Да, да ... получение требуемых данных в цикле - очень плохая идея! – kate

+0

... почему это «очень плохая идея»? – TessellatingHeckler

0

Это может работать, но это делает некоторые предположения:

$out -match '^ ' 
  1. $ вне всегда является строкой []. Принудите его с @($out), если это может быть одна строка.
  2. Вы используете PowerShell v4 или v5, поэтому -operator будет действовать как фильтр на массиве.
  3. Данные вашего примера точны, и все строки, которые вы хотите, начинаются с пробела, а все остальные строки - нет.