Home > Software engineering >  How to select a string and use it to find the difference between the times in Powershell
How to select a string and use it to find the difference between the times in Powershell

Time:01-09

I have a text file that has a bunch of lines that logs my DNS. It records the time and the site that my devices request DNS.

I have the file located on c:\data

$path = 'c:\data\dns.log'

I tried to query the log by simple match for a word "xfinity"

$Query = get-content -Path $path | Select-String -SimpleMatch "xfinity"

Then I query the first time it requested and the last time it requested

$Query | select -First 1

$Query | select -Last 1

$1st = $Query | select -First 1

Then I tried to "isolate" just the time

$1st -Split ("dnsmasq")

and I got stuck below because I don't know how to select just the time. Did a lot of googling but most of the stuff just went over my head

Jan 7 15:31:14

[250]: query[A] www.xfinity.com from 172.17.0.1

How do I just get the "time" of the first line and "time" of the last line and find the elapse time between them?

Here is an example of the dns.log would look like after Select-string to simple match "xfinity"

Jan  7 15:31:14 dnsmasq[250]: query[A] www.xfinity.com from 172.17.0.1
Jan  7 15:31:14 dnsmasq[250]: forwarded www.xfinity.com to 8.8.8.8
Jan  7 15:31:14 dnsmasq[250]: query[HTTPS] www.xfinity.com from 172.17.0.1
Jan  7 15:31:18 dnsmasq[250]: query[HTTPS] dss-dl-prod.aws-origin.xfinity.com from 172.17.0.1
Jan  7 15:31:18 dnsmasq[250]: forwarded dss-dl-prod.aws-origin.xfinity.com to 8.8.8.8
Jan  7 15:31:18 dnsmasq[250]: reply dss-dl-prod.aws-origin.xfinity.com is <CNAME>
Jan  7 15:33:18 dnsmasq[250]: reply dss-dl-prod.aws-origin.xfinity.com is <CNAME>

CodePudding user response:

  • Generally, note that Select-String does not directly return the text of matching lines, it returns Microsoft.PowerShell.Commands.MatchInfo objects whose .Line property contains the line text, alongside metadata.

    • In PowerShell (Core) 7 , you can use the -Raw switch to directly request the text.
    • In Windows PowerShell, you must access the .Line property value explicitly, either via (...).Line or by piping to Select-Object -ExpandProperty Line
  • Once you extract the actual line text, you'll be dealing with strings, so you'll need to parse those strings into the fields they contain.

    • The fields before : can unambiguously be extracted by using whitespace as the separator, which the unary form of the -split operator provides.
  • You can interpret strings such as 15:31:14 as time spans, simply by casting them to the [timespan] .NET type.

To put it all together:

# Get the lines of interest.
# Note: In PowerShell Core 7 , you could simplify to:
#  $matchingLines = Get-Content $path | Select-String -Raw xfinity
$matchingLines = (Get-Content $path | Select-String xfinity).Line

# From the lines of interest, extract the first and last line.
$firstMatchingLine, $lastMatchingLine = $matchingLines[0], $matchingLines[-1]

# Calculate the elapsed time between
# the last and the first matching line.
[timespan] (-split $lastMatchingLine)[2] - (-split $firstMatchingLine)[2]
  • Related