Special char in string

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
pe.ft
Posts: 8
Joined: 21 Sep 2010 13:53

Special char in string

#1 Post by pe.ft » 21 Sep 2010 14:30

Im trying to 'overload' the command line prompt primarily to customize command. The core of my script is the loop

Code: Select all

:CmdLoop
   call :ShowPrompt
   set /P "sCmd= "
rem   ParseCmd " %sCmd% "
   call ExecCmd " %sCmd% "
   set "sCmd= "
   goto :CmdLoop


ExecCmd is a .cmd file to execute the command, simply execute %*, it is a separate command.
It works with any sort of command, including pipes and redirections. Now I want to 'parse' the command line to change some internal commands of cmd.exe, like CD and add new.

This following code escape all special characters in %sCmd% that has a leading '" ' (dbl quote + space) and a trailing ' "' (space + double quote), Im not sure at 100% but this is necessary to have in-string double quotes and special characters in a variable.

Code: Select all

:ParseCmd
   set s=%*
   set s=%s:|=^|%
   set s=%s:&=^&%
   set s=%s:<=^<%
   set s=%s:>=^>%
   :: Trim dbl quotes
   set s=%s:~1,-1%
   :: Trim leading spaces
   for /f "tokens=* delims= " %%i in ("%s%") do set s=%%i
   goto :eof


In :ParseCmd the execution breaks depending on the content of %s%. My debugger is the echo command, so not sure of what happens. I also used the variant with surrounding dbl quote in %s% substitutions, like

Code: Select all

   set "s=%s:|=^|%"


Is there a solution for this?

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

Re: Special char in string

#2 Post by jeb » 21 Sep 2010 16:17

Hi pe.ft,

pe.ft wrote:My debugger is the echo command, so not sure of what happens.

that's a good idea, but you should use

Code: Select all

echo on

That can show you parts of the expansion.

You could read "The Secrets Behind Batch File Interpretation" http://www.lingubender.com/forum/viewtopic.php?f=12&t=615
Or the extended version at http://www.administrator.de/Die_Geheimnisse_des_Batch_Zeilen_Interpreters.html (German)
It explains that a batch line is parsed in multiple phases and how these phases work.

Then you probably decide to use in the most cases the DelayedExpansion, because it is more stable in the most situations.

hope it helps
jeb

amel27
Expert
Posts: 177
Joined: 04 Jun 2010 20:05
Location: Russia

Re: Special char in string

#3 Post by amel27 » 23 Sep 2010 07:13

jeb wrote:You could read "The Secrets Behind Batch File Interpretation"
wow! great work! thanks, jeb )
hmm... very useful information, may be it is possible (?):

Code: Select all

@echo off
set "$x=(^1="%%!"!2!"!%%")"
set $y=!=^^%%"

<nul set /p $z="Shaded chars: "& set $y
<nul set /p $z="Text before.: "& set $x
call :shade $x $y
<nul set /p $z="Text after..: "& set $x

EXIT

:shade
SetLocal EnableDelayedExpansion& Set q1="
For /L %%a In (0,1,1000) Do (
  Set "$a=!%~1:~%%a,1!"
  If Defined $a (
    For /L %%b In (0,1,100) Do (
      Set "$b=!%~2:~%%b,1!"
      If Defined $b If "!$a!"=="!$b!" If "!$b!"=="%%" (Set "$a=%%%%") Else Set "$a=^^!$a!"
    )
  Set "$s=!$s!!$a!"
))
For /F %%i In ("!$s!") Do EndLocal& Set "%~1=%%i"
Exit /B

result:

Code: Select all

Shaded chars: $y=!=^%"
Text before.: $x=(^1="%!"!2!"!%")
Text after..: $x=(^^1^=^"%%^!^"^!2^!^"^!%%^")

pe.ft
Posts: 8
Joined: 21 Sep 2010 13:53

Re: Special char in string

#4 Post by pe.ft » 23 Sep 2010 08:23

jeb wrote:You could read "The Secrets Behind Batch File Interpretation" http://www.lingubender.com/forum/viewtopic.php?f=12&t=615

I dont understand all the steps, but it's very intresting.

jeb wrote:Or the extended version at http://www.administrator.de/Die_Geheimnisse_des_Batch_Zeilen_Interpreters.html (German)
It explains that a batch line is parsed in multiple phases and how these phases work.

no german at all.

Im an "old school" batch user, when did norton commander, xtree and pc tools rule the world. I'll try the amel27's script, and also try to understand it.

My script doesnt work as expected, the 'call ExecCmd " %sCmd% "' contain

Code: Select all

   @echo off
   set s=%*
   set "s=%s:~1,-1%"
   %s%


I also put it in the main script as a sub, but in both cases strange things happens:

1. execution of batch files behave differently (probably due to what stated in the jeb article link).
2. after execution of some commands (only with embedded pipes?), pressing enter at prompt with an emply line executes after-pipe part. i.e. do the command
prompt> call /? | less
then
prompt>
(empty command), will execute less (with at least one space in the viewed file). Note that my 'less' is another batch file that simply call 'x:\dir\where\installed\less.exe %*'.
3. and others not explained due to posting limitation.

@jeb and @amel27
thanks for the useful informations, I'll keep on moving.

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

Re: Special char in string

#5 Post by jeb » 23 Sep 2010 12:48

amel27 wrote:hmm... very useful information, may be it is possible (?):


The problem is how to use it, with set you can see it, but how to use it?

Text after..: $x=(^^1^=^"%%^!^"^!2^!^"^!%%^")
echo %$x% - works only if delayedExpansion is disabled, else you need two carets for escaping one exclamation mark
echo "%$x%" - Now we are in the land of confusion

And there are characters which can't work with percent-expansion (not really possible to escape them), like <LF> or <CR>.
Or in the case of <LF> it makes your code totally crazy in blocks. :)

jeb

pe.ft
Posts: 8
Joined: 21 Sep 2010 13:53

Re: Special char in string

#6 Post by pe.ft » 23 Sep 2010 18:36

I found a solution to my problem. My approach was and is wrong. Jeb, u are right: how to parse the string? And more, how to modify before executed?

The source of my troubles was to overload internal commands (like CD, CLS, etc.). I coded a simple script to change directories called CDD, it primarily change dirs from disk to disk and add some sugar, say, u are in C:\somedir and want to change to J:\somethingelse. The command cd J:\somethingelse does nothing, you must specify the /D switch (curse u, CD) so cd /d J:\somethingelse.

How to overload cd to execute cdd? Simple using aliases, DOSKEY (curse u) so all I have to do is

Code: Select all

doskey cd=cdd $*

This open a new worm can but helps a lot. The initial script in the first post of the thread could be useful to override the prompt (adding colors using the sad $E parameter).

@amel27 my brain has not enugh neurons to understand your script :)

ghostmachine4
Posts: 319
Joined: 12 May 2006 01:13

Re: Special char in string

#7 Post by ghostmachine4 » 23 Sep 2010 18:50

is there a "cannot be done with anything else except batch" reason why you are doing all these?

pe.ft
Posts: 8
Joined: 21 Sep 2010 13:53

Re: Special char in string

#8 Post by pe.ft » 23 Sep 2010 20:01

changing directory in a command prompt (cmd.exe) window can be done only with a batch file, I say

C:\somedir> dir
... the dir command output ...
C:\somedir> myJavaScriptCD.js C:\somethingelse
C:\somedir> myPerlCD.pl C:\somethingelse
C:\somedir> myCPPCD.exe C:\somethingelse
C:\somedir> myBatchCD.cmd C:\somethingelse
C:\somethingelse> :)

myBatchCD does not change dir if you use setlocal/endlocal, for the same reason other languages fails.

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: Special char in string

#9 Post by orange_batch » 23 Sep 2010 20:09

I don't know if this will help, but do you know about pushd and popd?

pe.ft
Posts: 8
Joined: 21 Sep 2010 13:53

Re: Special char in string

#10 Post by pe.ft » 23 Sep 2010 20:17

Code: Select all

@echo off
:: Title: CDD
::      Change Drive and Directory.

   :: WARNING: dont use setlocal/endlocal if u really want to change directory
   :: Use 'DOSKEY CD=CDD %*' to override bult-in CD

   :: Parse parameters
   if "%~1" equ "" goto :CDHome
   if /I "%~1" equ "/?" goto :ShowHelp
   if /I "%~1" equ "/H" goto :ShowHelp
   if /I "%~1" equ "-H" goto :ShowHelp
   if "%~1" equ "~" goto :CDHome
   if "%~1" equ "-" goto :CDBackDir
   if not exist "%~1" (
      echo.^>^>^> Error: The directory '%~1' does not exists
      goto :End
   )
   :: Change directory to %1
   pushd "%~1"
   goto :End

:CDHome
   pushd %HomeDrive%%HomePath%
   goto :End

:CDBackDir
   popd
   goto :End

:ShowHelp
   echo.CDD - Change Drive and Directory
   echo.
   echo.Usage:
   echo.   CDD
   echo.   CDD ~
   echo.      Change to home directory of the current logged-in user.
   echo.   CDD path
   echo.      Change to path.
   echo.   CDD -
   echo.      Return to previous changed directory.
   echo.   CDD /?
   echo.   CDD /H
   echo.   CDD -H
   echo.      Show this help.

:End

ghostmachine4
Posts: 319
Joined: 12 May 2006 01:13

Re: Special char in string

#11 Post by ghostmachine4 » 23 Sep 2010 20:48

pe.ft wrote:changing directory in a command prompt (cmd.exe) window can be done only with a batch file, I say

C:\somedir> dir
... the dir command output ...
C:\somedir> myJavaScriptCD.js C:\somethingelse
C:\somedir> myPerlCD.pl C:\somethingelse
C:\somedir> myCPPCD.exe C:\somethingelse
C:\somedir> myBatchCD.cmd C:\somethingelse
C:\somethingelse> :)

myBatchCD does not change dir if you use setlocal/endlocal, for the same reason other languages fails.

if you are only doing it interactively on the command line, why is it such a hassle to just cd /D J:\somethingelse ?
If you are writing an automated script, eg in Perl, doing a chdir("J:\somewhereelse") will bring you to that directory in Perl and you can do whatever from that directory. I don't understand why there is a need to write your own "overloading" DOS commands. If you feel inadequate, use a programming language.

pe.ft
Posts: 8
Joined: 21 Sep 2010 13:53

Re: Special char in string

#12 Post by pe.ft » 23 Sep 2010 21:02

if you are only doing it interactively on the command line, why is it such a hassle to just cd /D J:\somethingelse ?
If you are writing an automated script, eg in Perl, doing a chdir("J:\somewhereelse") will bring you to that directory in Perl and you can do whatever from that directory. I don't understand why there is a need to write your own "overloading" DOS commands. If you feel inadequate, use a programming language.

I use lots of shells, I prefer CD stays the same in all of them. I hope u understand that, anyways...solved, sorry for this thread. bye

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: Special char in string

#13 Post by orange_batch » 24 Sep 2010 06:26

Trading performance for convenience? :?

pe.ft
Posts: 8
Joined: 21 Sep 2010 13:53

Re: Special char in string

#14 Post by pe.ft » 25 Sep 2010 06:27

orange_batch wrote:Trading performance for convenience? :?


lol, put more coal inside your steam-engine computer

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: Special char in string

#15 Post by orange_batch » 25 Sep 2010 08:03

No need to get nasty. 8) It depends on what you're doing, but such things may make a difference when processing large amounts of data. For example, using find/findstr to find a substring in a single line must be around a hundred times slower than doing a native substring replace and comparison.

Post Reply