2

I need to process files in order from oldest create date to newest

Is this correct or is there a better way to do it?

Thanks

Get-ChildItem -Path C:\Users\Tom\ -Filter "*.journal" | Sort-Object -Property CreationTime

ForEach ($sourcefile In $(Get-ChildItem $source | Where-Object { $_.Name -match "Daily_Reviews\[\d{1,12}-\d{1,12}\].journal" }))
{
    #### Process files in order from oldest to newest
    $file = $source+$sourcefile
 }
Slinky
  • 5,662
  • 14
  • 76
  • 130

3 Answers3

5

Short answer: No, but you're close.

Sorting(and other effects) only survive during a pipeline unless you store the result in a variable. So the first line where you sort is not used for you next line. However, you can combine them like this:

$source = "C:\Users\Tom\"   

Get-ChildItem -Path $source -Filter "*.journal" | 
Where-Object { $_.Name -match 'Daily_Reviews\[\d{1,12}-\d{1,12}\].journal' } | 
Sort-Object -Property CreationTime | ForEach-Object {
    #### Process files in order from oldest to newest
    $_.FullName
}
Frode F.
  • 52,376
  • 9
  • 98
  • 114
  • Thanks for this but I am a little confused on how to access the current item in the loop. Where is the current item in the loop stored? In my example it was kept in $sourcefile – Slinky Apr 12 '13 at 01:41
  • The current item in a pipeline is `$_`, in the `where-object` part, `$_` is the current object from `get-childitem`, while in the foreach loop, `$_` is a file that matches your regex and is sorted. – Frode F. Apr 12 '13 at 08:18
  • Thanks. That is good to know and this implementation works except it throws a warning: 'C:\Users\Tom\' is not recognized as a cmdlet, function, operable program or script file. Do you know what's going on there? – Slinky Apr 12 '13 at 10:24
  • Duh, I figured it out. This $source = C:\Users\Tom\ needed to be quoted so: $source = 'C:\Users\Tom\' – Slinky Apr 12 '13 at 10:28
  • Yeah, forgot that. Didn't notice it since I made the comment here on SO and not in PS ISE ;-) – Frode F. Apr 12 '13 at 10:41
2

Using sort-object seems like the right way to go about it, but your foreach is not using the sorted list. I'd add another | to pipe the output from sort-object to the foreach.

get-childitem -path c:\users\tom\ -filter "*.journal" |
sort-object -property creationtime |
where-object { $_.Name -match "Daily_Reviews\[\d{1,12}-\d{1,12}\].journal" } |
foreach-object {
    # $_ is the file we're currently looking at
    write-host $_.Name
}

The first command is get-childitem. It outputs a list of files in no particular order.

The unordered list of files is piped to sort-object. It outputs the same list of files but now sorted by creationtime.

The sorted list of files is piped to where-object. It outputs the filtered list of files, still sorted.

The filtered & sorted list of files is piped to foreach-object, so the body of foreach is run once for each file, with $_ being the file that's currently being processed. In this code I've written out the file name, but of course you would replace that with whatever you want to do with the file.

Nate Hekman
  • 6,507
  • 27
  • 30
  • Nate, What does that look like? For instance what order are the piped commands executed? Can you give me an example? Not sure where to insert the sort-object...Thanks – Slinky Apr 12 '13 at 01:51
  • Nate, Thanks for this explanation. Powershell is prompting for a value for the 4th piped parameter...Not sure what's going on there? – Slinky Apr 12 '13 at 10:21
  • It's because he starts the curly braces to the foreach loop on a seperate line. You need to start the scriptblock on the same line as the command. Atm, it runs: everything up to `foreach-object` when it can't find a scriptblock. Then as a seperate command, it defines a scriptblock. – Frode F. Apr 12 '13 at 10:43
1

Here's my take on this. The current object (e.g $_) is available inside the foreach scriptblock:

Get-ChildItem -Path C:\Users\Tom -Filter Daily_Reviews*.journal | 
Where-Object { $_.Name -match "Daily_Reviews\[\d{1,12}-\d{1,12}\].journal" } | 
Sort-Object -Property CreationTime | Foreach-Object{
   $_
}
Shay Levy
  • 121,444
  • 32
  • 184
  • 206