1

I have looked over quite a bit of answers to try and hack this together, but I am having issues getting this to run with a foreach type of statement, and I can't seem to get the regex to work as a one-line - if it did the foreach I am trying to use would work, but the regex ends up returning the whole line instead of the text I need to extract.

Here is what I am using currently:

$importPath = '.\file.LOG'
$string = Get-Content $importPath
$pattern = "FROM:<(.*?)> SIZE"
$result = [regex]::match($string, $pattern).Groups[1].Value
$result

I am fairly pedestrian when it comes to powershell and am having trouble wrapping my head around how to make this return a string from every matching line in the file.

If there is a way to do this with a one liner that isn't obtuse I would prefer that method, but I am fine with doing this in a script or by assigning variables as well.

wahyzcrak
  • 114
  • 12

2 Answers2

2

I suggest using a switch statement with the -file and -regex options:

$result = switch -file .\file.LOG -regex { 'FROM:<(.*?)> SIZE' { $Matches[1] } }
mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    Simple enough and this seems to work for what I need. I will read about why the switch command works for this. thank you very much – wahyzcrak Jan 19 '21 at 22:14
  • 1
    Glad to hear it, @wahyzcrak; my pleasure. The `switch` statement is quite powerful and, by PowerShell standards, performs well. As with `-match`, the [regular-expression matching operator](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Comparison_Operators#-match) operator, using `-Regex` populates the [automatic `$Matches` variable](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Automatic_Variables#matches). – mklement0 Jan 19 '21 at 22:16
  • Now to figure out how to do this in powershell: | sort | uniq -c | sort -nr I get that powershell is pretty neat, but it is a brain bender for me trying to go through documentation to figure anything out – wahyzcrak Jan 19 '21 at 22:26
  • 1
    @wahyzcrak, sounds like [`Group-Object`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/group-object) might do the trick; if you get stuck, I encourage you to ask a new question. Yes, PowerShell's documentation has historically been a trouble spot, but things are improving since they went open-source. – mklement0 Jan 19 '21 at 22:34
  • 1
    Group-Object is what I needed, and I ended up finding a github page for learning powershell that links to a lot of good resources and command cheat sheets that help me equate the bash commands I already know to the ps equivalents. Very helpful. Thanks again – wahyzcrak Jan 20 '21 at 17:10
  • 1
    Glad to hear it, @wahyzcrak - maybe the GitHub page contains the same links, but a while back I compiled a short list of resources in [this answer](https://stackoverflow.com/a/48491292/45375). – mklement0 Jan 20 '21 at 17:18
0

Use Select-String to perfect the regex.

Select-String -Path .\file.LOG -Pattern 'FROM:<(.*?)> SIZE'

or

(Get-Content -Path .\file.LOG) -match 'FROM:<(.*?)> SIZE'
Dan
  • 106
  • 4
  • Those both end up returning the entire line rather than the string in between. The thing I posted above only returns the email address it is looking for. – wahyzcrak Jan 19 '21 at 21:54
  • Do you have sample line items from .\file.log? – Dan Jan 19 '21 at 21:55
  • 2021-01-19T16:59:04.756Z,SERVERNAME\Relay,18D8BC913385E4F9,13,123.123.123.123:25,123.123.123.123:59946,<,MAIL FROM: SIZE=47618, For reference not every line in the log file matches, but I output all the results that do into a new text file and no cigar. – wahyzcrak Jan 19 '21 at 22:00
  • gc .\file.log | %{[regex]::Match($_, '(?is)MAIL FROM:<(.+?)>').groups[1].value} – Dan Jan 19 '21 at 22:13