Home > Enterprise >  PowerShell Count String in TxT
PowerShell Count String in TxT

Time:10-28

I have this script. Can I count $err1, $err2, ... ?

$logFolder = "C:\Users\boba\OneDrive\Desktop\TestFolder"
$err1 = "Asus"
$err2 = "Microsoft"
$err3 = "etcetera"

    function Read-Date {
  param(
    [String] $prompt
  )
  $result = $null
  do {
    $s = Read-Host $prompt
    if ( $s ) {
      try {
        $result = Get-Date $s
        break
      }
      catch [Management.Automation.PSInvalidCastException] {
        Write-Host "Date not valid"
      }
    }
    else {
      break
    }
  }
  while ( $true )
  $result
}

$startDate = Read-Date "Enter Start Date"
$endDate = Read-Date "Enter End Date"

    Get-ChildItem $logFolder -File -Recurse | Select-String -Pattern $err1
    Get-ChildItem $logFolder -File -Recurse | Select-String -Pattern $err2
    Get-ChildItem $logFolder -File -Recurse | Select-String -Pattern $err3
    #...

    Where-Object { $_.LastWriteTime -ge $startDate -and $_.LastWriteTime -le $endDate } | 
    select-Object FullName, LastWriteTime

Exacly for what I need this script is to read in log folder Error in all files between 2 dates. After script is finish create and open .txt (notepad) file and show how many $err1 is , how many $err2... and after that in txt show line by line errors.

It is possible?

Thank you! :)

Machine_Errors.txt - create by script after finish job


eg. 
***52 errors $err1***
     Details: 
     4 errors in 27.09.2021 - 11:02, 14:22, 19:00, .. 
     9 errors in 28.09.2021 - 19:12, 20:42, 21:00, ..

***0 errors $err2***

logs.txt (where script search) looks like this

9129318727412asakfwa---------a124314Asus129 27.09.2021 KUR a 11:02
8981284182841ouiruqw---------v9591929912009 27.09.2021 IRA a 11:55
1281284182848oiqwasq---------o901239lMicrosoft91200 28.09.2021 OLI a 20:42
...

CodePudding user response:

Your desired output is rather strange. First I recommend we create some objects to represent the lines. I added some more examples to the sample log file.

$tempfile = New-TemporaryFile

@'
9129318727412asakfwa---------a124314Asus129 27.09.2021 KUR a 11:02
8981284182841ouiruqw---------v9591929Microsoft912009 27.09.2021 IRA a 11:55
1281284182848oiqwasq---------o901239lMicrosoft91200 28.09.2021 OLI a 20:42
9129318727412asakfwa---------a124314Asus129 27.09.2021 KUR a 12:22
9129318727412asakfwa---------a124314Asus129 28.09.2021 KUR a 09:11
9129318727412asakfwa---------a124314Microsoft129 28.09.2021 KUR a 04:44
8981284182841ouiruqw---------v959192Microsoft9912009 27.09.2021 IRA a 16:55
1281284182848oiqwasq---------o901239lMicrosoft91200 28.09.2021 OLI a 17:42
'@ | Set-Content $tempfile -Encoding UTF8

Using your Read-Date function, I set the $startDate and $endDate appropriately. Then with a switch statement we read the file while also extracting 3 bits of information. In the end what is output is a PSCustomObject with 3 properties, Vendor, Date, Time where the date is within the provided dates.

$startDate = Read-Date "Enter Start Date"
$endDate = Read-Date "Enter End Date"

$output = switch -Regex -File $tempfile {
    '(\S )\s(\d{2}\.\d{2}\.\d{4}). (\d{2}:\d{2})$' {

        $date,$time = $matches[2..3]

        $compare = [datetime]::ParseExact($date,'dd.MM.yyyy',$null)

        if($compare -le $startDate -and $compare -ge $endDate){
            continue
        }

        $vendor = switch -Regex ($matches.1){
            'asus' {'ASUS'}
            'microsoft' {'Microsoft'}
            'etcetera' {'etcetera'}
            default {'Unknown'}
        }

        [PSCustomObject]@{
            Vendor = $vendor
            Date   = $date
            Time   = $time
        }
    }
}

Now we can take our nice objects and do some grouping to extract the desired information and output in the specified format.

$output | Group-Object -Property Vendor | Sort-Object -Property count -Descending | ForEach-Object {
    "***$($_.count) errors $($_.name)***"
    $_.group | Group-Object -Property Date | Sort-Object -Property count -Descending | ForEach-Object -Begin {"    Details:"} {
        "    $($_.count) errors in $($_.group.date|Select-Object -First 1) - $($_.group.time -join ', ')"
    }
    ""
}

This is the output

***5 errors Microsoft***
    Details:
    3 errors in 28.09.2021 - 20:42, 04:44, 17:42
    2 errors in 27.09.2021 - 11:55, 16:55

***3 errors ASUS***
    Details:
    2 errors in 27.09.2021 - 11:02, 12:22
    1 errors in 28.09.2021 - 09:11

Now you can just use Set-Content to write to a text file.

Pipe to Set-Content

$output | Group-Object -Property Vendor | Sort-Object -Property count -Descending | ForEach-Object {
    "***$($_.count) errors $($_.name)***"
    $_.group | Group-Object -Property Date | Sort-Object -Property count -Descending | ForEach-Object -Begin {"    Details:"} {
        "    $($_.count) errors in $($_.group.date|Select-Object -First 1) - $($_.group.time -join ', ')"
    }
    ""
} | Set-Content -Path \path\to\textfile.txt -Encoding UTF8

or inline with a subexpression

Set-Content -Path \path\to\textfile.txt -Encoding UTF8 -Value ($output | Group-Object -Property Vendor | Sort-Object -Property count -Descending | ForEach-Object {
    "***$($_.count) errors $($_.name)***"
    $_.group | Group-Object -Property Date | Sort-Object -Property count -Descending | ForEach-Object -Begin {"    Details:"} {
        "    $($_.count) errors in $($_.group.date|Select-Object -First 1) - $($_.group.time -join ', ')"
    }
    ""
})
  • Related