browsing files having special chars

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

browsing files having special chars

#1 Post by colargol » 24 Nov 2011 07:27

Hi guys

One more time, I don't manage to keep special chars ! and ^ in filenames when browsing files, because of EnableDelayedExpansion :(
I already tried so many things but none worked.
Can you help please?

Code: Select all

setlocal EnableDelayedExpansion

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

   :: preset and preset_name loose ! and ^ chars
   set "preset=%presets_path%\%%~i"
   set "preset_name=%%~i"

   :: I need DelayedExpansion enabled here

   :: some code
   :: ...
   set "_sortlist_!indexpos!_!cnt2!=!preset_name!"
   set /a presets_cnt+=1

)

:: display results
for /f "tokens=1* delims==" %%a in ('set _sortlist_') do (
   :: some code
)


I thought this would works but I have same results.

Code: Select all

setlocal EnableDelayedExpansion

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

   setlocal DisableDelayedExpansion
   for %%j in ("%%~i") do endlocal &set "preset=%presets_path%\%%~j"

   :: ...
)


Thank you

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: browsing files having special chars

#2 Post by jeb » 24 Nov 2011 08:37

Hi colargol,

your second solution is nearly the key. :)

You need to toggle between disabled/enabled delayed expansion.

Code: Select all

setlocal DisableDelayedExpansion
for /f "usebackq delims=" %%i in (`dir /B /O:N "%presets_path%\*.txt"`) do (

   :: delayed expansion must be of while expanding %%i
   set "preset=%presets_path%\%%~i"
   set "preset_name=%%~i"

   setlocal EnableDelayedExpansion
   :: some code
   :: ...
   set "_sortlist_!indexpos!_!cnt2!=!preset_name!"

   set /a presets_cnt+=1
   echo(!preset_name! , !presets_cnt!
   endlocal
)


But now you got another BIG problem, your variables are only visible in the short range of the setlocal EnableDelayedExpansion/ENDLOCAL block, and it's a bit tricky to handle this.

First you can move the "set /a presets_cnt+=1" behind the endlocal barrier.
And the variable "_sortlist_!indexpos!_!cnt2!" can be created with an own FOR-Block
Don't use :: remarks inside of blocks, as they can make some trouble.

Code: Select all

setlocal DisableDelayedExpansion
set /a presets_cnt=0
for /f "usebackq delims=" %%i in (`dir /B /O:N "%presets_path%\*.txt"`) do (

   :: delayed expansion must be of while expanding %%i
   set "preset=%presets_path%\%%~i"
   set "preset_name=%%~i"

   setlocal EnableDelayedExpansion

   for /F "delims=" %%p in ("!preset_name!") DO (
      for /F "delims=" %%v in ("_sortlist_!indexpos!_!presets_cnt!") DO (
         endlocal
         set "%%~v=%%~p"
      )
   )
   set /a presets_cnt+=1
)

set _sortlist


That is the obvious solution :wink:

hope it helps
jeb

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

Re: browsing files having special chars

#3 Post by colargol » 24 Nov 2011 13:37

Excellent! you're an encyclopedia of batch :!:
Thank you very much.

Is there any reason you used for /f instead a simple for ?

Code: Select all

      for /F "delims=" %%v in ("_sortlist_!indexpos!_!presets_cnt!") DO (



Here's my code (to be improved)
I had to use several endlocal for the same setlocal. I don't really like this but this avoids using additional variables.
Instead of this, I think I could use several levels of for.
I don't know what is the best solution.

Code: Select all

for /f "usebackq delims=" %%i in (`dir /B /O:N "%presets_path%\*.txt"`) do (
   set "preset_name=%%~i"

   setlocal EnableDelayedExpansion
   for /f "delims=" %%j in ("!preset_name!") do (
      set "preset=%presets_path%\!preset_name!"

      if /i "!preset_name!"=="%expreset%" (
         endlocal

      ) else (
         set skippreset=no
         set indexpos=0000%pos_unsort%

         for /f "usebackq eol=# tokens=*" %%a in (`type "!preset!"^| find "="`) do (
            for /f "tokens=1 delims=#" %%b in ("%%a") do (
               for /f "tokens=1* delims==" %%c in ("%%b") do (
                  set "v=%%c"
                  set "data=%%d"
                  call:trim v
                  call:trim data
                  if /i "!v!"=="disable" if /i "!data!"=="yes" (
                     set skippreset=yes
                     set /a presets_disabled+=1
                  )
                  if "!skippreset!"=="no" if /i "!v!"=="indexpos" (
                     for /f "useback tokens=*" %%x in ('!data!') do set "data=%%~x"
                     if !data! EQU +!data! if !data! GTR 0 if !data! LEQ %max_indexpos% (
                        set indexpos=0000!data!
                     )
                  )
               )
            )
         )

         if "!skippreset!" NEQ "no" (
            for /f %%v in ("!presets_disabled!") do (
               endlocal
               set "presets_disabled=%%~v"
            )
         ) else (
            set indexpos=!indexpos:~-5!
            set cnt=00!presets_cnt!
            set cnt=!cnt:~-3!
            set "varname=_sortlist_!indexpos!_!cnt!"
            for %%v in ("!varname!") do (
               endlocal
               set "%%~v=%%~j"
               set /a presets_cnt+=1
            )
         )
      )
   )
)

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: browsing files having special chars

#4 Post by jeb » 24 Nov 2011 14:10

colargol wrote:Excellent! you're an encyclopedia of batch :!:

Thanks :D

colargol wrote:Is there any reason you used for /f instead a simple for ?


Yes, FOR /F works with strings this way, a simple FOR works with filenames

Code: Select all

for %%v in ("this*fails") ...
for /F "delims=" %%v in ("this*works") ...

And you could transfer multiple values with a single FOR /F

Code: Select all

for /F "tokens=1-3 delims=," %%1 in ("11,22,33") do echo %%1#%%2#%%3


colargol wrote:I had to use several endlocal for the same setlocal. I don't really like this but this avoids using additional variables.
Instead of this, I think I could use several levels of for.
I don't know what is the best solution.

I would avoid to use more than one endlocal for one setlocal, it will become too complicated, especially if you run into an error.

hope it helps
jeb

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

Re: browsing files having special chars

#5 Post by colargol » 24 Nov 2011 14:50

You're right, for with delimiters may be the best solution.
I'll make some modification
Thanks :)

But I have a big surprise:

Code: Select all

set _sortlist_
display the expected result

but this looses ! and ^ again :o :o

Code: Select all

setlocal DisableDelayedExpansion

if "%presets_cnt%" NEQ "0" (
   for /f "tokens=1* delims==" %%a in ('set _sortlist_') do (

      echo "%%~b"
)

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: browsing files having special chars

#6 Post by jeb » 24 Nov 2011 15:18

:?: This should be impossible :!:

But it could be an effect of your unbalanced parenthesis :idea:

Code: Select all

if "%presets_cnt%" NEQ "0" (
   for /f "tokens=1* delims==" %%a in ('set _sortlist_') do (

      echo "%%~b"
)

Should be formatted as

Code: Select all

if "%presets_cnt%" NEQ "0" (
   for /f "tokens=1* delims==" %%a in ('set _sortlist_') do (

      echo "%%~b"
   )
... I expect here some code and a closing bracket
... and I assume here is also a SETLOCAL EnableDelayedExpansion


jeb

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

Re: browsing files having special chars

#7 Post by colargol » 24 Nov 2011 15:26

:oops: this is a mistake, I forgot to uncomment an endlocal in the for :oops:
sorry for time wasting!

What a noob I am!


final code (could help beginners like me) :

Code: Select all

for /f "usebackq delims=" %%i in (`dir /B /O:N "%presets_path%\*.txt"`) do (
   set "preset_name=%%~i"

   setlocal EnableDelayedExpansion
   for /f "delims=" %%j in ("!preset_name!") do (
      set "preset=%presets_path%\!preset_name!"
      set skippreset=no

      if /i "!preset_name!"=="%expreset%" (
         set skippreset=yes

      ) else (
         set indexpos=0000%pos_unsort%

         for /f "usebackq eol=# tokens=*" %%a in (`type "!preset!"^| find "="`) do (
            for /f "tokens=1 delims=#" %%b in ("%%a") do (
               for /f "tokens=1* delims==" %%c in ("%%b") do (
                  set "var=%%c"
                  set "data=%%d"
                  call:trim var
                  call:trim data
                  if /i "!var!"=="disable" if /i "!data!"=="yes" (
                     set skippreset=yes
                     set /a presets_disabled+=1
                  )
                  if "!skippreset!"=="no" if /i "!var!"=="indexpos" (
                     for /f "useback tokens=*" %%x in ('!data!') do set "data=%%~x"
                     if !data! EQU +!data! if !data! GTR 0 if !data! LEQ %max_indexpos% (
                        set indexpos=0000!data!
                     )
                  )
               )
            )
         )
      )

      if "!skippreset!"=="no" (
         set indexpos=!indexpos:~-5!
         set cnt=00!presets_cnt!
         set cnt=!cnt:~-3!
         set "varname=_sortlist_!indexpos!_!cnt!"
      )

      for /f "tokens=1-3 delims=," %%v in (""!skippreset!","!presets_disabled!","!varname!"") do (
         endlocal
         set "presets_disabled=%%~w"
         if "%%~v"=="no" (
            set "%%~x=%%~j"
            set /a presets_cnt+=1
         )
      )
   )
)

Post Reply