2

I am trying to search through the newest log file in directory for a particular string. The string reads Number of days since last service= and after the equals sign is a number. I want to extract that number for use later in my powershell program. This is what i have so far

$logDir= "C:logs\"
$latest = Get-ChildItem -Path $logdir | Sort-Object LastAccessTime -Descending | Select-Object -First 1
$findStr = Select-String -Path $latest.name -Pattern "Number of days since last service="

but now i am stuck. This is what it actually looks like in the log

<Msg>Number of days since last service =18</Msg>

so what i don't know how to do is extract the number between the equals sign and the < for this particular string

1
  • It's great that they're using an XML structured log format, so you don't have to use regular expressions and text slicing to get the data. :facepalm: Commented Jul 28, 2017 at 18:39

4 Answers 4

5

You can use Select-String with regex capture groups.

 $Matches = Select-String -Path $latest.name -Pattern "last service =(\d+)" | % {$_.Matches.Groups[1].Value}
Sign up to request clarification or add additional context in comments.

Comments

1

You've probably got your answer by now, but "Imma giv eya more!" Assuming we have these defined ahead of time:

$Log = "<Stuff><Msg>Number of days since last service =18</Msg></Stuff>"
$StringHint = "Number of days since last service =" 

1. Your typical Select-String method of doing things with Regexes. yep.

Select-String -InputObject $Log -Pattern "(?<=$StringHint)\d{1,}(?=<)" -AllMatches | % {$_.Matches.Groups[0].Value}

2. Doing the splits:

((($Log -split $StringHint)[1]) -split "<")[0]

3. The XML way. This only works for XML log files and if there is no other MSG tag (which is unlikely in this case). I chose to include this because I think it's cool how a simple type cast can dramatically alter how we can work with the data. Plus, it's a really easy way of stripping the nasty <'s and >'s away.

$xml = [xml]$Log
$EqualsLoc = $xml.Stuff.Msg.IndexOf("=")
$xml.Stuff.Msg.Substring($EqualsLoc+1)

The above would have been even better if you had a log file like this (yes, I know this is a configuration file and not a log file):

$XML = [xml]"<Application>
    <version>1.3.53</version>
    <AdvancedSettings>
        <Network>
            <InternetForWeebs>False</InternetForWeebs>
            <HackAllTheSystems>True</HackAllTheSystems>
            <L33tHandle>Gingervitis</L33tHandle>
        </Network>
    </AdvancedSettings>
    <BasicSettings>
        <Controls>
            <TheAnyKeyDesignation>0x42</TheAnyKeyDesignation>
            <CanHazCheeseburgerMode>True</CanHazCheeseburgerMode>
        </Controls>
    </BasicSettings>
    <Diagnostics>
        <DaysSinceLastService>18</DaysSinceLastService>
    </Diagnostics>
</Application>"

Then, getting the entry you needed would be something as easy as this:

$XML.Application.Diagnostics.DaysSinceLastService

2 Comments

Or if you don't know the path, and just know it's a Msg node, you can use Select-Xml as such: $XML | Select-Xml -XPath './/Msg' | Where{$_.Node.InnerXML -match "(?<=$StringHint)(\d{1,})(?=<)"} | %{$Matches[1]}
\d{1,} is the same as \d+ in that it matches one or more occurances.
0

Since you know the string before and after the data you want, you could just the -Replace operator to remove the unwanted text:

$Days = $findStr -replace '<Msg>Number\ of\ days\ since\ last\ service\ =','' -replace '</Msg>',''

Alternatively, since the information is the only number in the string, you could use -Match with \d+ (one or more numbers) to get the value.

$findStr -match '\d+'
$Days = $Matches.Values

1 Comment

For your first answer you could more simply do $Days = $findstr -replace '\<Msg\>Number of days since last service =\s*(\d+).*','$1'
0

I was able to do it like this

$result =[regex]::Match($findStr, '=([^/)]+)<').Groups[1].Value

1 Comment

Select-String outputs regex MatchInfo objects, so $findStr is already a thing you can use Groups and Value on, if you put the grouping in your select-string regex. (Instead of forcing it back into strings, and matching them as regexes again)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.