Question

We can see in a directory files ordered by Name in Windows Explorer.

If I try the same thing in the Windows command prompt it orders by name differently - correctly:

dir *.jpg /ON /B

cubierta.jpg
pag00.jpg
pag06.jpg
pag08.jpg
pag09.jpg
pag100.jpg
pag101.jpg
pag102.jpg
pag103.jpg
pag104.jpg
pag105.jpg
pag106.jpg
pag107.jpg
pag108.jpg
pag109.jpg
pag11.jpg, etc, etc, etc, ...

Is there a way to get dir to order by Name where it reads the numbers as a human would do?

Was it helpful?

Solution

Your best option (if possible) is to add enough leading zeros (two, in this case) to your smaller numbers so that the sort does come out as expected.

OTHER TIPS

Windows Explorer uses a special sorting function, StrCmpLogicalW, which is not used by cmd.exe, hence the differences in the output. You could write your own sorting program with it, though.

You might also be interested in Michael Kaplan's entries on this subject (from Raymond Chen's suggestion box).

He he he. Do you all want to know my solution?

I'm using a program called ImageMagic that converts my 200MB PDF files to JPG. At the end of the lengthy process it serializes all of the files in numerical order... So basically the file creation date increases in value slightly as each file is being written to the hard drive. Thus either of the following two batch file commands will write the files in 'correct' order:

dir *.jpg /ODN /B > files.txt

for /f "tokens=*" %%a in ('dir *.jpg /ODN /B') do (
    echo ^<page^>%%a^</page^> >>pages.xml.fragment
)

Thus the dir *.jpg /OD command orders the directory content by ascending (creation?) date, and we can completely ignore the actual file name.

Currently there are no built-in command line tools that can sort naturally. If you want please vote for the feature to make Microsoft change their mind

This however can be simulated with a regex replacement. On Windows you can use Jscript and VBS to do that. But the easiest way is using powershell. You can call it from cmd.exe like this

powershell -Command "(Get-ChildItem | Sort-Object { [regex]::Replace($_.Name, '\d+', { $args[0].Value.PadLeft(20) }) }).Name"

Of course you'll need to change the number in PadLeft(20) if your files contains a longer series of digits

How to sort by file name the same way Windows Explorer does?

A native batch solution can be found in Naturally Sort Files in Batch if your files have only a single number at the end

@echo off
setlocal enabledelayedexpansion
for %%a in (*.txt) do (
    set num=00000000000000000000%%a
    set num=!num:~-20!
    set $!num!=%%a
)
for /f "tokens=1,* delims==" %%a in ('set $0') do echo %%b

4NT/TCC/TC from JPSoft use natural sort order by default; alternately, if you have access to a GNU "sort" program, such as the Cygwin tools, you can do something like "ls -1 | /bin/sort -g" or "dir /b | \cygwin\bin\sort -g"; that will give you the filenames in natural sort order.

If you are constrained to tools that are native to windows, you can try the Windows Scripting tools and do something like use a FileSystemObject to get the filenames , and regular expressions to extract the numeric part of the filenames to use as keys in a Dictionary object. I'll leave the actual coding as an exercise to the reader :)

No, there's no way to do this. Windows Explorer uses a different approach to handle this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top