String generated from CL parameters...

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Bucko
Posts: 14
Joined: 05 Jun 2018 01:01

String generated from CL parameters...

#1 Post by Bucko » 24 Jun 2018 04:42

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"...)

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: String generated from CL parameters...

#2 Post by aGerman » 24 Jun 2018 05:15

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

Bucko
Posts: 14
Joined: 05 Jun 2018 01:01

Re: String generated from CL parameters...

#3 Post by Bucko » 24 Jun 2018 05:41

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...

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: String generated from CL parameters...

#4 Post by aGerman » 24 Jun 2018 06:02

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

Bucko
Posts: 14
Joined: 05 Jun 2018 01:01

Re: String generated from CL parameters...

#5 Post by Bucko » 24 Jun 2018 07:17

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...

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: String generated from CL parameters...

#6 Post by aGerman » 24 Jun 2018 07:31

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

Bucko
Posts: 14
Joined: 05 Jun 2018 01:01

Re: String generated from CL parameters...

#7 Post by Bucko » 24 Jun 2018 09:21

Works like a charm! Danke!!!

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: String generated from CL parameters...

#8 Post by aGerman » 24 Jun 2018 10:34

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

Bucko
Posts: 14
Joined: 05 Jun 2018 01:01

Re: String generated from CL parameters...

#9 Post by Bucko » 24 Jun 2018 14:29

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?

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: String generated from CL parameters...

#10 Post by aGerman » 24 Jun 2018 16:05

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

Post Reply