Page 1 of 1

String generated from CL parameters...

Posted: 24 Jun 2018 04:42
by Bucko
I would like to run a batch file via a command line with three parameters like this (e.g.):

Code: Select all

Test.bat 99 "Par 2" "Par 3"
The batch file should generate a string composed from the parameters:

Code: Select all

<Result><99><Two:Par 2><Three:Par 3>|
How this can be done? I have some success with my attempts, but I can not figure out how to generate the string without doublequotes (which are required in the CL because the parameters may include spaces).

After this, the string should be written to a text file.

(Potentially there could be more than two parameters of the type "Par 2", "Par 3"...)

Re: String generated from CL parameters...

Posted: 24 Jun 2018 05:15
by aGerman
The tilde sign (~) removes surrounding quotes. E.g. %2 vs. %~2. More interesting is how you handle strings like Two: and Three:. Where are they coming from? Especially if you pass more arguments to the batch script.

Steffen

Re: String generated from CL parameters...

Posted: 24 Jun 2018 05:41
by Bucko
Danke, Steffen!

Tilde, that's fine! It removes DQ from parameters. But my str is stil in DG, how to remove them?

Code: Select all

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

set str="<Result><%1><Two:%~2><Three:%~3>|"

echo %str%

echo %str% > Result.txt

REM cmd /u /c "echo %str% > Result.txt"
echo writes to Result.txt. The last line should write to a Unicode text file, but does not...

Re: String generated from CL parameters...

Posted: 24 Jun 2018 06:02
by aGerman

Code: Select all

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

set "str=<Result><%1><Two:%~2><Three:%~3>|"

echo !str!

>"Result.txt" echo !str!
Note that the quote is in front of the variable name.
Enclose the variable in exclamation marks for the output to make sure special characters like <>| are taken literally.
Make sure there is no space between string and redirection (>) if you dont want it in the file. It's my default to always write the redirection at the beginning of the line to avoid failures like that.

Steffen

Re: String generated from CL parameters...

Posted: 24 Jun 2018 07:17
by Bucko
OK, Steffen, my last problem:

Code: Select all

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

set "str=<Result><%1><Two:%~2><Three:%~3>|"

echo !str!

REM Works fine: >"Result.txt" echo !str!

REM Output to a Unicode file:
cmd /u /c "echo "!str!">ResultU.txt"
This last line works with quotes in "!str!", but then there are quotes in text file too...

Re: String generated from CL parameters...

Posted: 24 Jun 2018 07:31
by aGerman

Code: Select all

:: make sure !str! ain't expanded in the parent cmd.exe instance
setlocal DisableDelayedExpansion
:: /v:on enables the delayed expansion in the new cmd.exe instance, also the redirection doesn't belong to the new cmd.exe instance
>"ResultU.txt" cmd /v:on /u /c "echo !str!"
Steffen

Re: String generated from CL parameters...

Posted: 24 Jun 2018 09:21
by Bucko
Works like a charm! Danke!!!

Re: String generated from CL parameters...

Posted: 24 Jun 2018 10:34
by aGerman
What about
Bucko wrote:
24 Jun 2018 04:42
(Potentially there could be more than two parameters of the type "Par 2", "Par 3"...)
:?:

Code: Select all

@echo off
setlocal DisableDelayedExpansion

if "%~1"=="" exit /b 1
set "str=<Result><%~1>"

setlocal EnableDelayedExpansion
set /a "num=2, cnt=2"
for %%i in (
                "Two"         "Three"       "Four"        "Five"
  "Six"         "Seven"       "Eight"       "Nine"        "Ten"
  "Eleven"      "Twelve"      "Thirteen"    "Fourteen"    "Fifteen"
  "Sixteen"     "Seventeen"   "Eighteen"    "Nineteen"    "Twenty"
) do (
  set "n_!num!=%%~i"
  set /a "num+=1"
)

setlocal DisableDelayedExpansion
:loop
shift
if "%~1" neq "" if %cnt% lss %num% (
  setlocal EnableDelayedExpansion
  for /f "delims=" %%i in ("!str!") do for /f "delims=" %%j in ("!n_%cnt%!") do (
    endlocal
    set "str=%%i<%%j:%~1>"
  )

  set /a "cnt+=1"
  goto loop
)

set "str=%str%|"

>"ResultU.txt" cmd /v:on /u /c "echo !str!"
exit /b 0
I just had a look into my crystal ball though. You never answered my question of my first reply.

Steffen

Re: String generated from CL parameters...

Posted: 24 Jun 2018 14:29
by Bucko
Steffen, I am overwhelmed! Thank you very much!

"You never answered my question of my first reply." Yes, my fault. However, in my case this was irrelevant, the string composition was just an example, only the parameter parts are relevant for my batch file. Sorry...

In the meantime I found another problem associated to writing to a Unicode encoced text file. My expectation was that by my last line a file is generated which would be identical to a file generated by Notepad. This is not true, there are two differences. The batch-generated file (i) has no BOM, and (ii) at the end of the file automatically a new line (0D 00 0A 00) is appended!!! For my project the second difference is a problem, there should be no new line... This problem is probably unsolvable, right?

Re: String generated from CL parameters...

Posted: 24 Jun 2018 16:05
by aGerman
Using <NUL SET /P you can write a string without new line characters. Easy ways to add the BOM are dependent on your local settings. In the code below I assumed both that your default ANSI code page is Windows-1252 and that you saved the script Windows-1252-encoded. EDIT Changed it to a more generic way using UTF-7.

Code: Select all

@echo off
setlocal DisableDelayedExpansion

if "%~1"=="" exit /b 1
set "str=<Result><%~1>"

setlocal EnableDelayedExpansion
set /a "num=2, cnt=2"
for %%i in (
                "Two"         "Three"       "Four"        "Five"
  "Six"         "Seven"       "Eight"       "Nine"        "Ten"
  "Eleven"      "Twelve"      "Thirteen"    "Fourteen"    "Fifteen"
  "Sixteen"     "Seventeen"   "Eighteen"    "Nineteen"    "Twenty"
) do (
  set "n_!num!=%%~i"
  set /a "num+=1"
)

setlocal DisableDelayedExpansion
:loop
shift
if "%~1" neq "" if %cnt% lss %num% (
  setlocal EnableDelayedExpansion
  for /f "delims=" %%i in ("!str!") do for /f "delims=" %%j in ("!n_%cnt%!") do (
    endlocal
    set "str=%%i<%%j:%~1>"
  )

  set /a "cnt+=1"
  goto loop
)

set "str=%str%|"

:: save current OEM code page
for /f "tokens=*" %%a in ('chcp') do for %%b in (%%a) do set "oemcp=%%~nb"
:: change to UTF-7
>nul chcp 65000
:: characters ÿþ UTF-7-encoded
set "bom16_7_1252=+AP8A/g-"
:: change to Windows-1252 where ÿ is represented by byte 0xFF and þ by 0xFE which is the byte sequence of the UTF-16 LE BOM
>nul chcp 1252
:: write the BOM (the content of variable bom16_7_1252 was automatically converted to the current code page)
>"ResultU.txt" <nul set /p "=%bom16_7_1252%"
:: turn back to the default OEM code page
>nul chcp %oemcp%

>>"ResultU.txt" cmd /v:on /u /c "<nul set /p "=!str!""
exit /b 0
Steffen