You are not logged in.

#1 06 Jun 2012 18:39

pag
Member
Registered: 06 Jun 2012
Posts: 3

parsing command line parameters, space and quotes

If you happen to have an answer for the following, I'd be much appreciative.

I was reading your page at http://ss64.com/nt/syntax-esc.html.  Basically you say that if you use quotes on a DOS cmdline, the spaces no longer are delimiters in the interior.

However, when I'm attempting to parse command line parameters set as 'batchfile /p="param 1"' with space as my delimiter in a FOR loop, %a becomes either /p or /p="param (I think depending on if I'm doing a usebackq or not - but it may be varied if I attempted to subdivide at either " " or "=").

Is there a way that I can invoke the default delimiters minus certain ones in the standard set?  Or can use quotes as a way to "escape" the entire region until the next non-explicitly escaped quote (I may have need to accept something like /p="blah \"foo").  One potential solution that I am considering is to use one round using the "/" as my delimiter (or relying on the default parsing), then following up with the = being the only delimiter, potentially with the tokens as 1,* (where %%a would be "p" or "/p" and %%b is the rest of the string).  Using either a token=* or token=1,2 I seem to have the issue where my token breaks at the space, even though it's enclosed by quotes.  Ideally I'd like to use the space as my delimiter, as I'd like to be able to parse something like 'batchfile /p="said \"hi there" -o="123" invalid --help' where I break at the non-quoted spaces and discard or flag the broken tokens.

I'd be willing to share my batch file in whole (or just the relevant bits) if that would help you.  And I understand completely if you don't know the answer and/or don't have the time to investigate.  Linux grep/sed seems simple in comparison to DOS's for (or findstr).

Offline

#2 06 Jun 2012 19:07

pag
Member
Registered: 06 Jun 2012
Posts: 3

Re: parsing command line parameters, space and quotes

(using a .bat in windows 7, 64-bit cmd.com)

Offline

#3 07 Jun 2012 18:06

RG
Member
From: Minnesota
Registered: 18 Feb 2010
Posts: 362

Re: parsing command line parameters, space and quotes

You will want to use usebackq.
You can specify the delimiter set with FOR /F... see FOR  /? (multiple screens).


Windows Shell Scripting and InstallShield

Offline

#4 07 Jun 2012 19:56

pag
Member
Registered: 06 Jun 2012
Posts: 3

Re: parsing command line parameters, space and quotes

FOR simply does not do the same style of parsing as cmd.com or function CALLs.  If you use default delimiters (or any explicitly declared set including space), it breaks the tokens up at the spaces, regardless of if the space is enclosed in quotes or is not.

Basically what I'm saying is that echo 1%1 2%2 3%3 etc differs from FOR "usebackq" %%a in ('%*') do echo 1%%a 2%%b 3%%c
DOS is an inconsistent piece of suck

Here is my finally working solution for my whole issue (Windows search (in XP 4.0, Vista, 7, 8) is also an inconsistent piece of suck that needs to be augmented for unregistered plain-text file types), making sure to use the %1-type values

@echo off
setlocal enabledelayedexpansion
  echo for file and phrase, wildcards must be escaped. '.' is any single character rather than '?'
  echo * means repeat the previous character or class
  echo see http://www.computerhope.com/findstr.htm for full wildcard details
  echo to search in '*.bat', you would specify '.*\.bat'
  echo wonderfully complicated, isn't it?
  echo.
  REM read in params if they exist
  set prm=0
  set retval1=
  call :CVRTDELIM "%*"
  set into=%retval%
  call :INPARAMS %into%
  IF %prm%==0 (
    echo Command line usage: /d="C:\mydir\" /e=".*\.bat" /p="phrase to search"
    echo You may not use ~ or = within any of the parameters
    set /p directory="Directory To Search: "
    set /p extension="Files Named: "
    set /p phrase="Phrase in File: "
  )
  IF "a%directory%"=="a" (
    SET directory=.
  )
  IF "z%phrase%"=="z" (
    IF "z%extension"=="z" (
      echo You must input either a filename/type or a phrase to look for in the files
      @EXIT /b 1
    )
  )  
  set "sear=/b/s ^"%directory%^""
  SET exttxt=""
  SET phtxt=""
  IF NOT "a%extension%"=="a" (
    SET exttxt="|findstr "%extension%""
  )
  IF NOT "a%phrase%"=="a" (
    SET phtxt="|findstr /i /F:/ /C:"%phrase%""
  )
  for /f "usebackq tokens=*" %%a in ('%exttxt%') do set exttxt=%%~a
  for /f "usebackq tokens=*" %%a in ('%phtxt%') do set phtxt=%%~a
  SET seatxt="%sear%%exttxt%%phtxt%"
  for /f "usebackq tokens=*" %%a in ('%seatxt%') do set stripped=%%~a
  set strip2=%stripped:^^=%
  @echo on
  dir %strip2%
@endlocal
@echo Press any key to exit
@pause
@EXIT /b 0


:INPARAMS
REM  CALL :PRINTPARS %*
:IPL1
  IF z%1==z GOTO:EOF
  for /f "usebackq tokens=1,* delims=~" %%a in ('%1') do (
    IF NOT "z%%a"=="z" (
      set pt="%%a"
      set inval="%%b"
	
      for /f "usebackq tokens=*" %%g in ('!inval!') do set inval=%%~g
      for /f "usebackq tokens=*" %%g in ('!inval!') do set inval=%%~g

      if !pt!=="/p" (
        set phrase=!inval!
        set prm=1
      ) else (
	if !pt!=="/e" (
          set extension=!inval!
          set prm=1
        ) else (
          if !pt!=="/d" (
            set directory=!inval!
            set prm=1
          )
        )
      )
    )
  )
REM  echo " D:%directory% E:%extension% P:%phrase%"
  SHIFT
  GOTO :IPL1
  GOTO:EOF


:CVRTDELIMINDIV
  FOR /F "usebackq tokens=1,* delims==" %%a in ('%*') do (
	if NOT "z%%b"=="z" (
	  set retval=%%a~"%%~b"
    	  call :CVRTDELIMINDIV !retval!
        )
        if "z%%b"=="z" (
          set retval=%%~a
        )
  )
  GOTO:EOF

:PRINTPARS
    echo.%~0
    echo.%~1
    echo.%~2
    echo.%~3
    echo.%~4
    echo.%~5
    echo.%~6
    echo.%~7
    echo.%~8
    echo.%~9
  echo 0%*
  GOTO:EOF

:CVRTDELIM
  REM CALL :PRINTPARS %*
  CALL :CVRTDELIMINDIV %*
  REM CALL :PRINTPARS %retval%
  GOTO:EOF

Offline

Board footer

Powered by