Home > database >  Find all files with a particular extension, sorting them by creation time and copy them with a new n
Find all files with a particular extension, sorting them by creation time and copy them with a new n

Time:11-22

I am attempting to find recursively all files with the extension .raw and then sort them in ascending order of CreationTime. After that, I would like to copy each file to a new directory where the names are IMG_001_0001.jpg ... IMG_001_0099.jpg where I am using 4 digits in ascending order. It is important that the file name IMG_001_0001.jpg is the first one created and if there are 99 files, IMG_001_0099.jpg is the last file created.

I tried this:

Get-ChildItem 'F:\Downloads\raw-20221121T200702Z-001.zip' -Recurse -include *.raw | Sort-Object CreationTime | ForEach-Object {copy $_.FullName F:\Downloads\raw-20221121T200702Z-001.zip/test/IMG_001_$($_.ReadCount).jpg}

Thanks, -Marcos Camargo

CodePudding user response:

If I understand correctly you could do it like this:

$count = @{ Value = 0 }
Get-ChildItem 'F:\Downloads\raw-20221121T200702Z-001.zip' -Recurse -Filter *.raw |
    Sort-Object CreationTime | Copy-Item -Destination {
        'F:\Downloads\raw-20221121T200702Z-001.zip/test/IMG_001_{0:D4}.jpg' -f
            $count['Value']  
    }

Using D4 for the format string ensures your integers would be represented with 4 digits. See Custom numeric format strings for details.

As you can note, instead of using ForEach-Object to enumerate each file, this uses a delay-bind script block to generate the new names for the destination files and each source object is bound from pipeline.

Worth noting that the forward slashes in /test/ might bring problems and likely should be changed to backslashes: \test\.

CodePudding user response:

You don't need a hashtable to iterate... just use [int].

For the sake of clarity please don't use paths here that can easily be mistaken for a file rather than a directory name.

Get-Childitem does not work on files and if it does it's not portable.

Also that script block for -Destination is not likely to work as parameters defined outside it are not available inside. Nor is there any need to delay anything.

Something like this should be perfectly sufficient:

$ziproot ='F:\input_folder'
$count = 0
$candidates = Get-ChildItem  -Recurse -Filter '*.raw' |
Sort-Object CreationTime

ForEach($file in $candidates)
{
copy-item -source $_.FullName -Destination ('{0}/test/IMG_001_{1:D4}{2}' -f $ziproot,  $count, $_.Extension )
}

(Try using foreach($var in $list) {commands} where you can, it's faster than foreach-object by about a factor of 10.)

  • Related