1

The windows explorer does display in correct order. For example: filename1.txt, filename2.txt, filename11.txt etc. When I tried the DIR command with different options could not get the same behaviour. It displays filename1.txt, filename11.txt, filename2.txt.

Is there any way to sort it so that numeric ordering is preserved?

user3330840
  • 6,143
  • 7
  • 26
  • 39
  • You had this tagged with [dos] and [ms-dos], but I'm willing to bet that you are ***not*** using DOS. It would be impossible for you to do so on a modern version of Windows. It is, however, important for you to tell us whether you're using PowerShell or the Windows Command Prompt. – Cody Gray - on strike Feb 14 '16 at 14:49
  • I updated the tags to specifically mean windows command line. Windows 7 and up will be fine. – user3330840 Feb 14 '16 at 14:51
  • If this isn't a PowerShell question, this isn't a duplicate, so I've reopened it. Unfortunately, I don't think this is possible. Explorer uses the special function StrCmpLogical to do sorting, but the command prompt doesn't. It always uses lexicographic sorting. Your workaround is the obvious one, pad the file names with 0s. – Cody Gray - on strike Feb 14 '16 at 14:55

1 Answers1

2
@ECHO Off
:: dir list in numeric-value order
SETLOCAL
:: %1= directoryname; default current directory
SET "targetdir=%~1"
IF NOT DEFINED targetdir SET "targetdir=.\*.*"
:: remove variables starting $
FOR  /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
SET /a maxnumlength=0
SET "manyzeroes=0000000000000000"
SET "manyzeroes=%manyzeroes%%manyzeroes%%manyzeroes%%manyzeroes%"
:: analyse list of filenames
FOR /f "delims=" %%a IN (
  'dir /b /a-d "%targetdir%" '
  ) DO CALL :detnlen "%%a"

:: build list of filenames
FOR /f "delims=" %%a IN (
  'dir /b /a-d "%targetdir%" '
  ) DO CALL :setname "%%a"

FOR  /F "tokens=1*delims=:" %%a In ('set $ 2^>Nul') DO ECHO %%b

GOTO :EOF

:detnlen
SET "name=%~1"
SET /a numlength=0
SET "action=L"
:detnloop
IF %action%==F SET "action=B"
SET "post=%name:~0,1%"&SET "name=%name:~1%"
IF "%post%" geq "0" IF "%post%" leq "9" (
 SET /a numlength+=1
 SET "action=F"
)
IF %action% neq B IF DEFINED name GOTO detnloop
IF %numlength% gtr %maxnumlength% SET /a maxnumlength=%numlength%
GOTO :EOF

:setname
SET "name=%~1"
SET "pre="
SET "nums="
SET "action=L"
:snloop
IF %action%==F SET "action=B"
SET "post=%name:~0,1%"&SET "name=%name:~1%"
IF "%post%" geq "0" IF "%post%" leq "9" (
 SET /a numlength+=1
 SET "action=F"
 SET "nums=%nums%%post%"
)
IF %action%==L SET "pre=%pre%%post%"&SET "post="
IF %action% neq B IF DEFINED name GOTO snloop ELSE SET "post="
IF %action%==F SET "post="
IF DEFINED nums SET "nums=%manyzeroes%%nums%"
IF DEFINED nums CALL SET "nums=%%nums:~-%maxnumlength%%%"
SET "$%pre%%nums%%post%%name%=:%~1"
GOTO :EOF

Oh, my!

There are no inbuilt switches to show the directory in that odd way, but this has all the hallmarks of a challenge.

OK - it's insanely slow, but it appears to work.

The principle is to determine the longest sequence of initial-numerics as maxnumlength then assign the name of the detected file to an environment variable starting $ and with a name constructed from the filename with the numeric part leading-zero-padded. set $ then lists the $ variables in alphabetic order; select the value, which is the original filename.

Magoo
  • 77,302
  • 8
  • 62
  • 84