Sorting data?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
colargol
Posts: 49
Joined: 28 Sep 2011 13:23
Location: france

Sorting data?

#1 Post by colargol » 28 Sep 2011 13:43

Hello

First thanks to the authors of the site, I learned many things here :)
I hope someone can help me for the following problem:


I have a script that browse *.txt files. They are sorted by name.
For each file, I read an indexpos (an integer from 0 to 100) given in the file.

Now, what I want to do is sorting filenames using their indexpos
(2 files can have the same indexpos)

e.g:

Code: Select all

files     %indexpos% in the file
--------------------
"a.txt"    indexpos=3
"b.txt"    indexpos=4
"c.txt"    indexpos=1
"d.txt"    indexpos=3
"e.txt"    indexpos=2
"f.txt"    indexpos=3


a piece of code:

Code: Select all

the code looks like this:
for /f "usebackq delims=" %%i in (`dir /B /O:N "%presets_path%\*.txt"`) do (

   :: get indexpos from the file (this works)
   set indexpos=!data!

   :: ... ???
)

:: sort filename...



and I wnat to display this:

Code: Select all

c.txt
e.txt
a.txt
d.txt
f.txt
b.txt


I have a solution that works using arrays but it does too many iterations. It is not optimized at all
Have a better idea?

Thanks for help :D

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: Sorting data?

#2 Post by Ed Dyreen » 28 Sep 2011 13:47

'
Did you try

Code: Select all

sort /?
already ?

colargol
Posts: 49
Joined: 28 Sep 2011 13:23
Location: france

Re: Sorting data?

#3 Post by colargol » 28 Sep 2011 14:20

I know sort command but I have no idea how I can use it for my problem.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Sorting data?

#4 Post by dbenham » 28 Sep 2011 14:36

SORT could be made to work, but colargol only wants to display the filenames so the output of SORT would have to be processed. Given the current structure of the code so far, this would most likely require a temporary file or else major restructuring of the code.

I think this code should work, assuming colargol can fill in the code that gets the indexpos. The code assumes indexpos will not exceed 9999, additional zeros could be used if higher numbers are needed.

Code: Select all

@echo off
setlocal enableDelayedExpansion
for /f "usebackq delims=" %%i in (`dir /B /O:N "%presets_path%\*.txt"`) do (
  :: get indexpos from the file (this works)
  set indexpos=000!data!
  set indexpos=!indexpos:~-4!
  set "_mysort_!indexpos!%%i=%%i"
)
for /f "tokens=2* delims==" %%A in ('set _mysort_') do echo %%A

I think this method will work as long as none of the filenames contain = or !

Dave Benham

colargol
Posts: 49
Joined: 28 Sep 2011 13:23
Location: france

Re: Sorting data?

#5 Post by colargol » 28 Sep 2011 15:05

Great :D
It works, but some filenames contain "=" so it only displays a part of the filename :?

I don't understand your code for now but thanks for help!

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Sorting data?

#6 Post by dbenham » 28 Sep 2011 15:28

This version using SORT and a temporary file should work even if = is in filename. (It still won't work if filenames contain !)

Code: Select all

@echo off
setlocal enableDelayedExpansion
set tempfile="%temp%\_%random%.txt"
(
  for /f "usebackq delims=" %%i in (`dir /B /O:N "%presets_path%\*.txt"`) do (
    :: get indexpos from the file (this works)
    set indexpos=000!data!
    echo !indexpos:~-4! %i
  )
)|sort>%tempfile%
for /f "usebackq tokens=1*" %%A in (%tempfile%) do echo %%B
del %tempfile%


Dave Benham

colargol
Posts: 49
Joined: 28 Sep 2011 13:23
Location: france

Re: Sorting data?

#7 Post by colargol » 28 Sep 2011 15:46

I'll have a look tomorrow. Time to sleep for me :)
I replaced your code with this and it seems it works with all chars.
Many thanks :)

Code: Select all

@echo off
setlocal enableDelayedExpansion
for /f "usebackq delims=" %%i in (`dir /B /O:N "%presets_path%\*.txt"`) do (
  :: get indexpos from the file (this works)
  set indexpos=000!data!
  set indexpos=!indexpos:~-4!
  set "_mysort_!indexpos!%%i=/"
)

for /f "tokens=* delims=/" %%A in ('set _mysort_') do (
   set var=%%A
   set var=!var:~12,-2!
   echo !var!
)

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Sorting data?

#8 Post by dbenham » 28 Sep 2011 16:04

Very clever solution to = problem. :D

I think you can safely remove "delims=/". It doesn't hurt, but it is not doing anything positive either.

I think all solutions posted so far will still fail if ! is in filename because delayed expansion is on. The filename will be corrupted when %%i is expanded in the first FOR loop if it contains !

All posted solutions will also fail if filename begins with ; because of imiplicit EOL=; in first FOR loop. It will skip filenames beginning with ;

Both problems should be rare, but there are possible solutions if the need arises.

Addendum - On second thought, you can still run into problems with = with your modification if two similar filenames containing = are both assigned the same indexpos.

Example: Suppose "part1=1.txt" and "part1=2.txt" are both assigned indexpos=3. Then they both will attempt to set a variable named _mysort_0003part1. Obviously the last one set wins, and you will lose the earlier file


Dave Benham

colargol
Posts: 49
Joined: 28 Sep 2011 13:23
Location: france

Re: Sorting data?

#9 Post by colargol » 29 Sep 2011 06:57

dbenham wrote:Addendum - On second thought, you can still run into problems with = with your modification if two similar filenames containing = are both assigned the same indexpos.

Example: Suppose "part1=1.txt" and "part1=2.txt" are both assigned indexpos=3. Then they both will attempt to set a variable named _mysort_0003part1. Obviously the last one set wins, and you will lose the earlier file
you are right!

My final solution is to add a counter to ensure the vars are uniques:

Code: Select all

@echo off
setlocal enableDelayedExpansion
set cnt=0

for /f "usebackq delims=" %%i in (`dir /B /O:N "%presets_path%\*.txt"`) do (
  :: get indexpos from the file (this works)
  set indexpos=0000!data!
  set indexpos=!indexpos:~-5!
  set cnt2=00!cnt!
  set cnt2=!cnt2:~-3!
  set "_mysort_!indexpos!_!cnt2!=%%i"
  set /a cnt+=1
)

for /f "tokens=1,* delims==" %%A in ('set _mysort_') do echo %%B


I also tried your solution with | sort

This provides unsorted lines

Code: Select all

(
...
)>%tempfile%


but this generates errors; don't understand why :shock:
but it does't matter, I retain first solution. :)

Code: Select all

(
...
)|sort>%tempfile%


I recommend not to use ! char in my help file :P
(can I check a filename has a ! with enabledelayedexpansion enable?)

Thanks again for your help

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Sorting data?

#10 Post by dbenham » 29 Sep 2011 08:04

I think you nailed it :!:
At first I thought your files would not sort properly in case of indexpos tie. But then I realized your sorted DIR output coupled with your ascending cnt handles indexpos tie. Nice work :D

Dave Benham

Post Reply