PowerShell filter files by date in name

7,937

I realize this is a 4 year old question at this point. But I figured I'd add a new answer since there are currently no other up-voted ones.

The way I'd go about this is parsing the date into an actual DateTime object from the file name. Then you can use normal date comparisons rather than string comparisons. The most common way to do this is using a Calculated Property as part of a Select-Object statement. In the example below, we add a calculated property called ParsedDate to the existing output.

$RetainedDays = 7
$FileNameRegex = "\w+_(\d+)\.\w+"
$culture = [System.Globalization.CultureInfo]::InvariantCulture
$ProcessFiles = Get-ChildItem -Path $RootPath -Recurse | 
  Select-Object *,@{
    L='ParsedDate';
    E={ if ($_.Name -match $FileNameRegex) { 
      $strDate = $matches[1];
      [DateTime]::ParseExact($strDate,"yyyyMMdd",$culture)
    }
  }
} | Where { $_.ParsedDate -lt (Get-Date).AddDays(-$RetainedDays) }

The regular expression actually makes things more complicated than they might need to be though. If your files all have the exact same naming pattern of app_<DATE>.log, you can skip the Regex and simplify by letting ParseExact do all the work like this. You just need to escape the literal characters in the format string by surrounding them with single quotes.

$RetainedDays = 7
$culture = [System.Globalization.CultureInfo]::InvariantCulture
$ProcessFiles = Get-ChildItem -Path $RootPath -Recurse | Select FullName,@{
  L='ParsedDate';
  E={ [DateTime]::ParseExact($_.Name,"'app_'yyyyMMdd'.log'",$culture) }
} | Where { $_.ParsedDate -lt (Get-Date).AddDays(-$RetainedDays) }

Technically speaking, you could also do the date parsing inside the Where clause and skip the intermediate Select clause. But I'll leave that as an exercise for the reader.

Share:
7,937

Related videos on Youtube

gazsiazasz
Author by

gazsiazasz

Updated on September 18, 2022

Comments

  • gazsiazasz
    gazsiazasz over 1 year

    I have many files with different names per day. How can I filter them by the date in their name?

    For example:

    app_20130505.log
    app_20130506.log
    app_20130507.log
    app_20130508.log
    app_20130509.log
    

    And my code snippet:

    $RetainedDays = 7
    $FileNameRegex = "\w+_(\d+)\.\w+"
    $ArchiveBoundary = $(Get-Date -Format yyyyMMdd) - $RetainedDays
    $ProcessFiles = Get-ChildItem -Path $RootPath -Recurse |
        Where-Object { $_.Name -match $FileNameRegex }
    

    I have regex filter for it : \w+_(\d+)\.\w+, that gives me back the date in $Matches variable, but how can I combine them, and get back the file list, with those files, which older than 7 days?

    • tony roth
      tony roth almost 11 years
      I think questions like this are better for stackoverflow then serverfault.
    • gazsiazasz
      gazsiazasz almost 11 years
      It's possible, but I doesn't know, how can I move the question into stackoverflow. Otherwise it's not a programming question. PowerShell is a script language, what is useful to system administrators, like me and possibly for you.
  • Bruce
    Bruce almost 11 years
    And I agree with Tony, stackoverflow would be the better choice.