SimonS
SimonS

Reputation: 1973

Find newest file in directory, then select all files with same DateTime

With this command, I can search for the newest file in a directory:

gci C:\temp | sort LastWriteTime -descending | select -first 1

My directory is rather large, containing 60'000+ txt files. Running this command takes:

PS C:\xy> measure-command {gci C:\temp | sort LastWriteTime -descending | select -first 1}


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 13
Milliseconds      : 465
Ticks             : 134657703
TotalDays         : 0.000155853822916667
TotalHours        : 0.00374049175
TotalMinutes      : 0.224429505
TotalSeconds      : 13.4657703
TotalMilliseconds : 13465.7703

As you can see, this command takes a long time to finish.

My task is to get all the files which have the same LastWriteTime Property as the file which the command returns (to the minute).

I tried something like this:

$file = gci C:\temp -OutVariable files | sort LastWriteTime -descending | 
        select -first 1 | % { $_.LastWriteTime }
$myfiles = $files | ? {$_.LastWriteTime -like $file}

when I compare $file which is the found LastWriteTime, and $myfiles which should contain all files with the same LastWriteTime, $myfiles always includes only one file - this is because the seconds are different for each object:

PS C:\xy> $file

Montag, 21. November 2016 13:10:08

How can I find the files I need by comparing their lastwritetime properties?

Upvotes: 0

Views: 1167

Answers (4)

n4pd3f
n4pd3f

Reputation: 26

It seems like you want time only and not date, so, there is a FileInfo Method that I would utilize to make the comparison easier.

Grab the time you're after:

$time = (Get-ChildItem -Path C:\temp -Filter "*.txt" | Sort-Object LastWriteTime -Descending | Select-Object -First 1).LastWriteTime.ToShortTimeString()

Then, grab the files that match:

Get-ChildItem -Path C:\temp -Filter "*.txt" | Sort-Object LastWriteTime | Where-Object { $_.LastWriteTime.ToShortTimeString() -eq $time }

Upvotes: 0

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174485

$myfiles always includes only one file - this is because the seconds are different for each object:

Then compare only the parts of the timestamp that you're interested in - in this example we compare down to the minute:

$Timestamp = $file.ToString('yyyyMMddHHmm')

$myfiles = $files | ? {$_.LastWriteTime.ToString('yyyyMMddHHmm') -eq $file}

Upvotes: 3

Jamiec
Jamiec

Reputation: 136104

I think you'll need to just compare Year, Month, Day, Hour and Minute

$myfiles = $files | ? {$_.LastWriteTime.Year -eq $file.Year `
                     -and $_.LastWriteTime.Month -eq $file.Month `
                     -and $_.LastWriteTime.Day -eq $file.Day `
                     -and $_.LastWriteTime.Hour -eq $file.Hour `
                     -and $_.LastWriteTime.Minute -eq $file.Minute }

Upvotes: 1

whatever
whatever

Reputation: 891

Couple of ideas to possibly speed this up at least a bit. Not sure how much they will achieve, thou. And this is not tested, so might contain errors ;)

$file = ((gci C:\temp -OutVariable files).LastWriteTime | sort -Descending)[0]

$myfiles = $files.Where{$_.LastWriteTime -match $file}

Upvotes: -1

Related Questions