Home > Back-end >  How to move thousands of image files into subfolders each with 400 image files?
How to move thousands of image files into subfolders each with 400 image files?

Time:10-04

I have 2000 images and I want to move them into different folders. Each folder should contains 400 images and each folder is in a different path.

\Desktop\images contains:

0001.jpeg
0002.jpeg
...
2000.jpeg

The files should be moved to the folders:

\Desktop\Project\Folder1\images:

0001.jpeg
0002.jpeg
...
0400.jpeg

\Desktop\Project\Folder2\images

0401.jpeg
0402.jpeg
...
0800.jpeg

\Desktop\Project\Folder3\images:

1801.jpeg
1802.jpeg
...
1200.jpeg

\Desktop\Project\Folder4\images:

1201.jpeg
1202.jpeg
...
1600.jpeg

\Desktop\Project\Folder5\images:

1601.jpeg
1602.jpeg
...
2000.jpeg

Graphical display of the folders

CodePudding user response:

Here is a commented batch file for this file moving task with some extras to make it interesting (for me):

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=%UserProfile%\Desktop\images"
if not exist "%SourceFolder%\*.jpeg" goto :EOF

set "DestinationPath=%UserProfile%\Desktop\Project"
set "DestinationName=Folder"
set "FolderNameLength=6"
set "MaxFileCount=400"

setlocal EnableDelayedExpansion
set "FolderNumber=0"
set "FileCount=%MaxFileCount%"
set "DestinationFolder=!DestinationPath!\!DestinationName!"

rem Search for all non-hidden subfolders with a name starting with the
rem destination folder name and having a number append and determine
rem the greatest folder number in all existing folder names. Folder
rem names with one or more leading zeros are not supported by this code.

for /F "delims=" %%I in ('dir "!DestinationFolder!*" /AD-H-L /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /R "^folder[0123456789][0123456789]*$"') do (
    set "FolderName=%%I"
    if !FolderName:~%FolderNameLength%! GTR !FolderNumber! set "FolderNumber=!FolderName:~%FolderNameLength%!"
)

rem Determine the number of *.jpeg files in the images folder in the folder
rem with greatest folder number if there is an existing images folder at all.

if exist "!DestinationFolder!!FolderNumber!\images\" (
    set "FileCount=0"
    for /F "eol=| delims=" %%I in ('dir "!DestinationFolder!!FolderNumber!\images\*.jpeg" /A-D /B 2^>nul') do set /A FileCount =1
)

rem Get a list of JPEG files in source folder loaded into memory of the
rem Windows command processor ordered by name and move all these files
rem with making sure that no images folder has more than the number of
rem JPEG files as defined above. The code below is not capable moving
rem files with one or more exclamation marks because of always enabled
rem delayed expansion.

rem Note: The command DIR orders the file names strictly alphabetically
rem       and not alphanumerical as done by Windows File Explorer. So
rem       the JPEG file names should have all the same number of digits.

for /F "eol=| delims=" %%I in ('dir "!SourceFolder!\*.jpeg" /A-D /B /ON 2^>nul') do (
    set /A FileCount =1
    if !FileCount! GTR %MaxFileCount% (
        set "FileCount=1"
        set /A FolderNumber =1
        md "!DestinationFolder!!FolderNumber!\images"
    )
    echo Moving file "%%I" to "!DestinationFolder!!FolderNumber!\images\"
    move "!SourceFolder!\%%I" "!DestinationFolder!!FolderNumber!\images\"
    if errorlevel 1 set /A FileCount-=1
)
endlocal
endlocal

This batch file works on no destination folder existing at all as well as some destination folders already existing in which case the number of JPEG files in destination folder with greatest number is found out to determine how much JPEG files to move additionally to the images folder of the FolderX with greatest number.

Please note that SourceFolder, DestinationPath, DestinationName, FolderNameLength and MaxFileCount must be adapted to local requirements.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • dir /?
  • echo /?
  • endlocal /?
  • findstr /?
  • goto /?
  • if /?
  • md /?
  • move /?
  • rem /?
  • set /?
  • setlocal /?

Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul and |. The redirection operators > and | must be escaped with caret character ^ on the FOR command lines to be interpreted as literal character swhen Windows command interpreter processes these command lines before executing command FOR which executes the embedded dir command lines without or with findstr in a separate command process started in background with %ComSpec% /c and the command line within ' appended as additional arguments.

CodePudding user response:

As you are using an Operating System which is equipped with , here's an alternative which utilises that instead:

DistributeFiles.ps1

$DesktopPath = [System.Environment]::GetFolderPath([System.Environment SpecialFolder]::Desktop)

$SourceDir = $DesktopPath   "\images"
$FileMask = "*.jpeg"
$DestDir = $DesktopPath   "\Project"
$FilesPerDir = 400
$DestStartNum = 1

$i = 0
Get-ChildItem -Path $SourceDir -Filter $FileMask -Name | Sort-Object | ForEach-Object {
   New-Item -Path ($DestDir   "\Folder"   $DestStartNum) -Type Directory -Force > $Null
   Move-Item ($SourceDir   "\"   $_) ($DestDir   "\Folder"   $DestStartNum)
   $i  
   If ($i -Eq $FilesPerDir) {
      $DestStartNum  
      $i = 0
   }
}

In order to remain on topic with your tag, you could run that script from a Command Prompt window like this:

%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy RemoteSigned -File "L:\ocation\Of\DistributeFiles.ps1"

CodePudding user response:

Another way to do it would be to use the PowerShell that is already on your supported Windows system. This cmd .bat file script runs a PowerShell script that will use the first four (4) digits of the .jpeg file name to determine to which directory it should be moved. Files not beginning with four (4) digits will not be moved.

Put both the .bat and .ps1 file in the same directory. When you are satisfied that the correct directories will be created and the files will be moved to the correct directory, remove the -WhatIf from both the mkdir and Move-Item commands.

=== DistributeFiles.bat

@powershell -NoLogo -NoProfile -File "%~dp0%~n0.ps1"

=== DistributeFiles.ps1

$ProjectPath = Join-Path -Path $Env:USERPROFILE -ChildPath 'Desktop\Project';
$NFilesPerDirectory = 400;
Get-ChildItem -File -Path (Join-Path -Path $Env:USERPROFILE -ChildPath 'Desktop\images') -Filter '*.jpeg' |
    ForEach-Object {
        # Check to see if the filename starts with four (4) digits.;
        if ($_.BaseName -match '^(\d{4}).*') {
            $FolderNumber = [math]::Floor([int]$Matches[1] / $NFilesPerDirectory);
            $FolderName = 'Folder'   $FolderNumber.ToString();
            $FolderPath = Join-Path -Path $ProjectPath -ChildPath $FolderName;
            # If the destination directory does not exist, create it.;
            if (-not (Test-Path -Path $FolderPath)) { mkdir $FolderPath -WhatIf | Out-Null }
            # Move the file to the destination directory.;
            Move-Item -Path $_.FullName -Destination $FolderPath -WhatIf
        }
    }
  • Related