Home > front end >  How can I filter by day and month in a txt file with powershell
How can I filter by day and month in a txt file with powershell

Time:09-21

I use logging in my script and write this with day, month and time:

$LogTime = Get-Date -Format "dd-MM HH:mm"

I want to remove all lines older than a month from the file I wanted to do it like this but it doesn't work:

$DateOld = (get-date (get-date).addDays(-30) -UFormat "%d-%m")
    
$RemoveLog = get-content -Path C:\.....\Log\UserLog.txt | where {($_.split('-'))[1] -gt $DateOld} | Set-Content "C:\......\Log\out.txt" | Out-Null
Remove-Item -Path C:\........\Log\UserLog.txt -Force | Out-Null
Rename-Item -Path "C:\.........\Log\out.txt" -NewName "UserLog.txt" | Out-Null

The line in the log looks like this:

20-09 11:30 ::: Line with info about log

CodePudding user response:

Something like this. Remarks: -the powershell array gets slow on big arrays, you will then better use an generic.list

  • its just a first draft, depending on the exact requirements and logfile you will need some fine-tuning and / or exception handling, but you should get the idea:
#tmp 20 09 2021

$logfile = 'your path'
[array]$log = Get-Content $logfile
$newLog = @()
$limitDate = (Get-Date).AddDays(-30)
foreach ($line in $log) {
  $regex = [regex]::match($line, '(\d{2}-\d{2})\s\d{2}:\d{2}')
  if($regex.Success -eq 'True') {
    $lineDate = [datetime]::ParseExact($regex.Groups[1].Value.ToString(), "dd-MM", $null)
    if ($lineDate -ge $limitDate) {
      $newLog  = $line
    }
  }
  else {
    [console]::WriteLine('Big Exception in Logfile! Will Quit')
    exit
  }

}

Remove-Item $logfile -Force
if(-not (Test-Path $logfile)) {
  $newLog | Out-File $logfile
}
else {
  [console]::WriteLine('Big Exception in Logfile! Please Investigate')
}

CodePudding user response:

You may use [datetime]::ParseExact() method to read your file dates and times as [datetime] objects. You may use Move-Item to overwrite a file with a new name using its -Force parameter.

$DateOld = (Get-Date).AddDays(-30)

Get-Content UserLog.txt | Where {
    [datetime]::ParseExact([string](-split $_)[0..1],'dd-MM HH:mm', 
    [System.Globalization.DateTimeFormatInfo]::InvariantInfo) -ge $DateOld
} | Set-Content out.txt
Move-Item out.txt UserLog.txt -Force

Using -split value, value splits based on a single space delimiter. Since we only want the first two elements, we use range 0..1 for the first two resulting elements. Casting to [string] rejoins the split items with a space delimiter.

  • Related