0

I have several files in a folder, those are .xml files.

I want to get a value from those files. A line in the file, could look like this:

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

What i'm trying to do is get the value 49,99 in this case.

I am able to get the line out of the file with:

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

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

}

But getting just the value in "" i don't get how. I've also played around with

$Strings.totaldisksize

But no dice.

Thanks in advance.

user3019059
  • 187
  • 1
  • 17

3 Answers3

1

You can do this in one line as follows:

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

The Select-String will give you a collection of objects that contains information about the match. The line property is the one you're interested in, so you can pull that directly.

Using the -replace operator, every time the .line property is a match of totaldisksize, you can run the regex on it. The $1 replacement will grab the group in the regex, the group being the part in parentheses (\d+,\d+) which will match one or more digits, followed by a comma, followed by one or more digits.

This will print to screen because by default powershell will print an object to the screen. Because you're only accessing the .line property, that's the only bit that's printed and also only after the replacement has been run.

If you wanted to explicitly use a Write-Host to see the results, or do anything else with them, you could store to a variable as follows:

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

The above stores the results to an array, $sizes, and you iterate over it by piping it to the Foreach-Object or %. You can then access the array elements with $_ inside the block.

arco444
  • 22,002
  • 12
  • 63
  • 67
  • Thank you. It works. Any chance i could bother you to explain it? I don't get how it's writtes with no write-host. – user3019059 Nov 21 '14 at 12:11
  • It seems to get the whole line if there are no , in the value between the "". Like: It is possible it could both understand "50,2" and "50"? Thanks. – user3019059 Nov 21 '14 at 17:18
  • Answer to my last comment is here: http://stackoverflow.com/questions/27075793/find-number-between-quotes/27075804?noredirect=1#comment42662795_27075804 – user3019059 Nov 22 '14 at 09:37
0

But.. but.. PowerShell knows XML.

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

Output

49,99

Or walk the tree and return the content of "drives":

$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

Output

PS> $drives

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

PS> $drives.freespace
22,33

XPath query of "//drives" = Find all nodes named "drives" anywhere in the XML tree. Reference: Windows PowerShell Cookbook 3rd Edition (Lee Holmes). Page 930.

evilSnobu
  • 24,582
  • 8
  • 41
  • 71
-1

I am not sure about powershell but if you prefer using python below is the way of doing it.

import re

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

Output

49,99
Kannan Mohan
  • 1,810
  • 12
  • 15