2014-11-21 2 views
0

У меня есть несколько файлов в папке, это файлы .xml.Как получить значение из Select-String

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

<drives name="Virtual HD ATA Device" deviceid="\\.\PHYSICALDRIVE0" interface="IDE" totaldisksize="49,99"> 

Что я пытаюсь сделать, это получить значение 49,99 в этом случае.

Я смог получить строку из файла с:

$Strings = Select-String -Path "XML\*.xml" -Pattern totaldisksize 

foreach ($String in $Strings) { 
     Write-Host "Line is" $String 

} 

Но получить только значение «» я не понимаю, как. Я также играл с

$Strings.totaldisksize 

Но не кубики.

Заранее спасибо.

ответ

1

Вы можете сделать это в одной строке следующим образом:

$(select-string totaldisksize .\XML\*.xml).line -replace '.*totaldisksize="(\d+,\d+)".*','$1' 

Select-String даст вам коллекцию объектов, которая содержит информацию о матче. Свойство line - это тот, который вас интересует, поэтому вы можете напрямую его перенести.

Использование оператора -replace, каждый раз, когда свойство .line соответствует совпадению totaldisksize, вы можете запустить регулярное выражение на нем. Замена $1 будет захватывать группу в регулярном выражении, причем эта группа является частью в круглых скобках (\d+,\d+), которая будет соответствовать одной или нескольким цифрам, а затем запятой, а затем одной или несколькими цифрами.

Это будет печатать на экране, потому что по умолчанию powershell будет печатать объект на экране. Поскольку вы только получаете доступ к свойству .line, это единственный бит, который был напечатан, а также только после замена была выполнена.

Если вы хотите явно использовать Write-Host, чтобы увидеть результаты, или сделать что-нибудь еще с ними, можно хранить в переменной следующим образом:

$sizes = $(select-string totaldisksize .\XML\*.xml).line -replace '.*totaldisksize="(\d+,\d+)".*','$1' 
$sizes | % { Write-Host $_ } 

Вышеизложенные сохраняет результаты в массив, $sizes , и вы перебираете его по трубопроводу до Foreach-Object или %. Затем вы можете получить доступ к элементам массива с помощью $_ внутри блока.

+0

Спасибо. Оно работает. Есть ли вероятность, что я могу вам объяснить это? Я не понимаю, как это написано без записи. – user3019059

+0

Конечно, обновил ответ. Надеюсь, что это яснее? – arco444

+0

Amazing. Спасибо. – user3019059

0

Я не уверен насчет powershell, но если вы предпочитаете использовать python, это способ сделать это.

import re 

data = open('file').read() 
item = re.findall('.*totaldisksize="([\d,]+)">', data) 
print(item[0]) 

Выход

49,99 
0

Но .. но .. PowerShell знает XML.

$XMLfile = '<drives name="Virtual HD ATA Device" deviceid="\\.\PHYSICALDRIVE0" interface="IDE" totaldisksize="49,99"></drives>' 
$XMLobject = [xml]$XMLfile 
$XMLobject.drives.totaldisksize 

Выход

49,99 

Или ходить по дереву и возвращать содержимое "дисков":

$XMLfile = @" 
<some> 
    <nested> 
    <tags>  
     <drives someOther="stuff" totaldisksize="49,99" freespace="22,33"> 
     </drives> 
    </tags> 
    </nested> 
</some> 
"@ 

$drives = [xml]$XMLfile | Select-Xml -XPath "//drives" | select -ExpandProperty node 

Выходных

PS> $drives 

someOther   totaldisksize   freespace 
---------   -------------   --------- 
stuff      49,99    22,33 

PS> $drives.freespace 
22,33 

XPath запрос «// приводов "= Найти все узлы с именем" диски "в любом месте i n дерево XML. Справка: Windows PowerShell Cookbook 3rd Edition (Lee Holmes). Страница 930.

+0

Хорошо .. Что, если строка не выглядит так? – user3019059

+0

Что общего между этими файлами? Могу ли я взять «totaldisksize» как обычное свойство ChildNode? Могу я взять ? – evilSnobu

+0

Строка всегда будет содержать Иногда мне нужен totaldisksize, иногда freespace. – user3019059

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