PDA

Показать полную графическую версию : Распределить значения Select-String по разным переменным.


Uragan66
28-11-2019, 13:41
Добрый день всем!
Возник вроде бы и банальный вопрос, но не могу придумать как это сделать, точнее знаний не хватает...
При парсинге, да и не только, бывает необходимость значения, вытащенные с помощью Select-String, взять в разные переменные.
К примеру такой блок кода:
$b = ($a | Select-String -Pattern '[\S\s]*<title>([^"]+)</title>[\S\s]*var filmSource.*"/([^"]+txt)"[\S\s]*' -AllMatches).Matches|
ForEach-Object {"$($_.Groups[1].Value)`n$($_.Groups[2].Value)"Подскажите, пожалуйста, как значения 1 и 2 определить в разные переменные ?

DJ Mogarych
28-11-2019, 13:58
Вот бы получить примерный файл того, что вы парсите, а также что именно нужно из этого файла.

В общем случае, вместо select-string лучше использовать where:


$g,$notg = (gc c:\temp\123.txt).where({$_ -match 'g'},'Split')

Uragan66
28-11-2019, 14:11
DJ Mogarych, примеры то разные могут быть. В переменной $b в данном коде:
Сверхъестественное (15 сезон)
/playlist/338619.txt

в продолжении кода эти два значения нужно использовать в разных командах. Вот и хотелось бы взять их в разные переменные.
Пока что выкрутился с помощью рег. выражений:
$t = $b | Foreach {$_ -replace "(.*)`n(.*)","`$1"}
$r = $b | Foreach {$_ -replace "(.*)`n(.*)","`$2"}
Но это некрасиво, да и неправильно наверное.
Файл для примера прикрепил.

DJ Mogarych
28-11-2019, 14:25
Ну, если в переменной всего 2 строки, то можно вообще просто:

$t = $b[0]
$r = $b[1]


или так:


$t,$r = (gc c:\temp\123.txt).where({$_ -notmatch '/'},'Split')

Uragan66
28-11-2019, 14:59
DJ Mogarych, спасибо большое.
К сожалению так не получится. По строкам:
$t = $b[0]
$r = $b[1]
я сразу пробовал, но в переменные берутся не строки, а первые символы строк.
А, если применять where, то нужно вывод сохранять во временный файл, что не очень удобно, их в коде и так уже 2.
Можно наверное весь код переделать с Where-Object вместо Select-String, но что-то с ним у меня не получалось взять два нужных значения.

Таким кодом:
$t,$r = $k.where({$_ -notmatch '/'},'Split')
получилось отлично
DJ Mogarych, ещё раз большое спасибо за подсказку.

DJ Mogarych
28-11-2019, 16:41
Uragan66, да, я ошибся - хотел написать во втором примере $b.where, но забыл убрать gc из копипасты.
Впрочем, вы и сами прекрасно догадались.

dirigar
05-12-2019, 10:50
В регулярке группе можно дать имя группе захвата: "(?<name>text)", а потом создать объект с такими же именами.
powershell:

$reg = New-Object System.Text.RegularExpressions.Regex '[\S\s]*<title>(?<Title>[^"]+)</title>[\S\s]*var filmSource.*"/(?<FilmSource>[^"]+txt)"[\S\s]*', 'Multiline,IgnoreCase'
$a = gc -Raw ./123.txt
$b =
if (($a | Out-String) -match $reg ) {
$Matches.Remove(0)
New-Object psobject -Property $Matches
$Matches.Clear()
}
;
$b


выдаст:

Title FilmSource
----- ----------
Сверхъестественное (15 сезон) смотреть онлайн бесплатно все серии playlist/338619.txt




© OSzone.net 2001-2012