Finding latest file in multiple sub-directories

by Muzznz at 2013-02-26 17:02:48

Noob here so forgive me if this seems basic. I have a directory that has about 90 sub-directories, we’ll call these Top Level Directories. Each of these TLDs has a number of sub directories .

For each of these TLDs I am wanting to find the latest file , name date and time of.

I have found the following code, which works if I run it within the TLD, but I want to run it at the level where I can see all 90 TLDs, and have it “walk” down each TLDs structure to give me the answers.

I should end up with the latest file in each of the TLDs, about 90 of them :slight_smile:

dir -recurse | ?{$.PsIsContainer -ne $true} | sort -prop LastWriteTime | select -last 1
by DonJ at 2013-02-26 17:14:59
First rule of Don’t do the “noob” apology ;). No need.

Eighth rule: Try to use command names (Where-Object) vs. punctuation aliases (?) - just so other noobs can follow along more easily!

So, my understanding is that you want to exclude the sub-directories of your top-level directories, which your current command will not do. Is that correct? You can do this if you can set a variable that contains your toppest-level directory. So, if your structure is:


Where A and B are your top-level directories, you could do this:

$topmost = "Topmost"
Get-ChildItem -Path $topmost -recurse |
Where { $PsIsContainer -and $.Parent -eq $topmost } |
ForEach { Get-ChildItem -Path $
.FullName |
Where { $_.PsIsContainer -eq $False } |
Sort -Property LastWriteTime |
Select -Last 1 }

Note that your original command specifically excluded FILES… so it’d never work for what you want. What I did was to get all the TLDs, and then ForEach one of those, get a full directory listing of JUST FILES from those. I then sorted those and selected, like you did. The trick is I only kept directories whose parent is my topmost folder. That’ll exclude any subs of the TLDs, provided none of the TLDs has the same name as the topmost.

Hope that helps. But please make sure you understand the logic here… don’t just take the command, ask questions if you don’t understand WHY it works. Or, ask if it doesn’t actually work ;).
by Muzznz at 2013-02-27 16:27:24
Thanks for that DonJ. I will apologise for doing the Noob apology thing then. :slight_smile:

I see what this is doing, and I tried it on my original directory (90 TLDs containing a total of 919940 files, 74793 folders and 1.96 TB in size). I left it running for 18 hours, but it never finished what it was doing.

So I created a test directory structure (3 TLDS containing 15932 files, 1674 folders and 95.7 GB in size). It runs for about 10 seconds then returns me to the drive prompt, with no output.
by DonJ at 2013-02-27 16:36:40
Yeah… that’s a lot of files. I’ll note that I see a typo in my above - $_PSIsContainer should have a dot after the underscore. So definitely check my syntax.

I ran this on a little test folder setup here and it was great. On a million files… I wouldn’t expect it to work well. Too much memory. You probably won’t be able to do this as a one-liner like this; you’ll probably need to write a recursive function of your own so that you can check a single folder and output whatever, instead of trying to do it all in a big wodge.
by Muzznz at 2013-02-27 16:42:12
Hmm, put the . in the correct place and tried again with the 3 TLD test directory, and runs for 5 seconds and back to file system prompt. No output. :frowning:
by DonJ at 2013-02-27 16:46:54
Time to debug it :).

Whenever I’ve got a multi-command pipe, I debug by removing the last command on the pipeline and seeing if I get anything. I keep working backwards until I start getting what I expected for that point… and when that happens, it usually tells me where the problem is. Without sitting right in front of your system, working with YOUR data, I can’t debug it for you. But debugging is good sk1llz to hone!