Search code examples
batch-filealphabetical-sort

Batch file: sorting folders and files alphabetically


The batch file below recursively echos files and folders while adding some simple formatting, such as indenting to show the recursion depth, adding "/ " before folder names, "*" before certain files, and skipping folders named "Archive". It works great except that files and folders are sorted randomly, rather than alphabetically. How could this be changed to sort both files and folders alphabetically?

@echo off
setlocal disableDelayedExpansion
pushd %1
set "tab=   "
set "indent="
call :run
exit /b

:run

REM echo the root folder name
for %%F in (.) do echo %%~fF
echo ------------------------------------------------------------------

set "folderBullet=\"
set "fileBullet=*"

:listFolder
setlocal

REM echo the files in the folder
for %%F in (*.txt *.pdf *.doc* *.xls*) do echo %indent%%fileBullet% %%F  -  %%~tF

REM loop through the folders
for /d %%F in (*) do (

  REM skip "Archive" folder
  if /i not "%%F"=="Archive" (

  REM if in "Issued" folder change the file bullet
  if /i "%%F"=="Issued" set "fileBullet= "

  echo %indent%%folderBullet% %%F
  pushd "%%F"
  set "indent=%indent%%tab%"
  call :listFolder

  REM if leaving "Issued folder change fileBullet
  if /i "%%F"=="Issued" set "fileBullet=*"

  popd
))
exit /b

Solution

  • Very little change required. Convert FOR loops to FOR /F running sorted DIR commands. The /A-D option lists files only, and /AD lists directories only.

    This version sorts files by name

    @echo off
    setlocal disableDelayedExpansion
    pushd %1
    set "tab=   "
    set "indent="
    call :run
    exit /b
    
    :run
    
    REM echo the root folder name
    for %%F in (.) do echo %%~fF
    echo ------------------------------------------------------------------
    
    set "folderBullet=\"
    set "fileBullet=*"
    
    :listFolder
    setlocal
    
    REM echo the files in the folder
    for /f "eol=: delims=" %%F in (
      'dir /b /a-d /one *.txt *.pdf *.doc* *.xls* 2^>nul'
    ) do echo %indent%%fileBullet% %%F  -  %%~tF
    
    REM loop through the folders
    for /f "eol=: delims=" %%F in ('dir /b /ad /one 2^>nul') do (
    
      REM skip "Archive" folder
      if /i not "%%F"=="Archive" (
    
      REM if in "Issued" folder change the file bullet
      if /i "%%F"=="Issued" set "fileBullet= "
    
      echo %indent%%folderBullet% %%F
      pushd "%%F"
      set "indent=%indent%%tab%"
      call :listFolder
    
      REM if leaving "Issued folder change fileBullet
      if /i "%%F"=="Issued" set "fileBullet=*"
    
      popd
    ))
    exit /b
    

    To sort by extension first, then by name, simply change /ONE to /OEN.