Just noticed that VAR=%VAR:*STRING% does eliminate the previous string but VAR=%VAR:STRING*% doesn't elimiate next string
so how to eliminate the next string ? my current code is :
:CheckEnvironmentVariable Location Variable Value
IF [%1] EQU [System] (
ECHO Querying system
) ELSE (
IF [%1] EQU [User] (
ECHO Querying User Environments
FOR /F "usebackq tokens=*" %%x IN (`REG QUERY "HKCU\Environment"`) DO (
SET CURRVARS=%%x&&SET CURRVARS=!CURRVARS:REG_*=!
ECHO !CURRVARS!
)
) ELSE (
ECHO ERROR ^^! Invalid Environment Variable Location "%1"
)
)
EXIT /B
which is doen't work as expected
I am afraid I don't understand what you want to do. However, I guess that is related to this "possible" solution:
#echo off
setlocal EnableDelayedExpansion
set "VAR=This is a STRING long value"
echo VAR: %VAR%
rem Eliminate string "previous" to "STRING" (including it)
set "tail=%VAR:*STRING=%"
echo Tail: "%tail%"
rem Eliminate string "next" to "STRING" (not including it)
set "head=!VAR:%tail%=!"
echo Head1: "%head%"
rem Eliminate string "next" to "STRING" (including it)
set "head=!VAR:STRING%tail%=!"
echo Head2: "%head%"
Output:
VAR: This is a STRING long value
Tail: " long value"
Head1: "This is a STRING"
Head2: "This is a "
Based upon the code you have submitted, I'm not even sure why you would want to try to split the string at that particular place. There is a consistent string in every single line that would be returned by your reg.exe command, and that is REG_. The beauty of that paricular string is that it will always be non space separated, non localized, and never contain special characters. If you split at that point, you know that the substring you're looking for, will always be every token following its remainder, e.g. EXPAND_SZ your string(s); SZ your string(s).
So here's some example code which uses that method, but please be aware that it wil not work as intended should you have any variable defined within the System or User Environments with names including the case insensitive string REG_:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
:Ask4Var
ClS
Set "sName="
Set /P "sName=Please enter the name of the variable you wish to verify>"
If Not Defined sName GoTo Ask4Var
(
Set %sName%
) 2>NUL | %SystemRoot%\System32\findstr.exe /BIL "%sName%=" 1>NUL || (
Echo There is no variable named %sName% in the current environment
%SystemRoot%\System32\timeout.exe /T 3 1>NUL
GoTo Ask4Var
)
Set "Env=System"
Set "RootKey=HKLM"
Set "SubKey=System\CurrentControlSet\Control\Session Manager\Environment"
%SystemRoot%\System32\choice.exe /C SU /N /M "[S]ystem OR [U]ser?"
If ErrorLevel 2 (
Set "Env=User"
Set "RootKey=HKCU"
Set "SubKey=Environment"
)
Set "Reg=%SystemRoot%\System32\reg.exe"
Set "ValueString="
For /F Delims^=^ EOL^= %%G In (
'%Reg% Query "%RootKey%\%SubKey%" /V /F "%sName%" /E ^|
%SystemRoot%\System32\find.exe "REG_"'
) Do (
Set "Result=%%G"
SetLocal EnableDelayedExpansion
For /F "Tokens=1,*" %%H In ("!Result:*REG_=!") Do (
EndLocal
Set "ValueString=%%I"
)
)
If Not Defined ValueString (
Echo There is no variable named %sName% in the %Env% environment
%SystemRoot%\System32\timeout.exe /T 3 1>NUL
GoTo Ask4Var
)
Echo The expanded string value of %sName% is %ValueString%.
%SystemRoot%\System32\timeout.exe /T 7 1>NUL
GoTo :EOF
Related
So what I'm trying to do is create a find for multiple people where it in the text file it will say names and numbers like
Example of text file:
Beth
1234567891
Jay
2134456544
This is the best way I can explain what I'm trying to do:
#echo off
set "file=Test1.txt"
setlocal EnableDelayedExpansion
<"!file!" (
for /f %%i in ('type "!file!" ^| find /c /v ""') do set /a n=%%i && for /l %%j in (1 1 %%i) do (
set /p "line_%%j="
)
)
set /a Name=1
set /a Number=2
Echo Line_%Name%> %Name%.txt (Im trying to get this to say line_2 to say 1st line in the text file)
Echo Line_%Number%> %Name%.txt (Im trying to get this to say line_2 to say 2nd line in the text file)
:Start
set /a Name=%Name%+2 (These are meant to take off after 1 so lines 3,5,7,9 so on)
set /a Number=%Number%+2 (These are meant to take off after 2 so lines 4,6,8,10 so on)
Echo Line_%Name%
Echo Line_%Number%
GOTO :Start
so the outcome would be
In Beth.txt:
Beth
1234567891
So every name will be a file name and the first line in a file. I will change it later so I can do a addition in each text file.
Name: Beth
Number: 1234567891
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
SET "filename1=%sourcedir%\q65417881.txt"
rem make sure arrays are empty
For %%b IN (name number) DO FOR /F "delims==" %%a In ('set %%b[ 2^>Nul') DO SET "%%a="
rem Initialise counter and entry array
SET /a count=0
SET "number[0]=dummy"
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
IF DEFINED number[!count!] (SET /a count+=1&SET "name[!count!]=%%a") ELSE (SET "number[!count!]=%%a")
)
rem clear out dummy entry
SET "number[0]=dummy"
FOR /L %%c IN (1,1,%count%) DO (
rem replace spaces with dashes
SET "name[%%c]=!name[%%c]: =-!"
rem report to console rem report to console
ECHO Name: !name[%%c]! Number: !number[%%c]!
rem generate name.txt file
(
ECHO !name[%%c]!
ECHO !number[%%c]!
)>"%destdir%\!name[%%c]!.txt"
)
GOTO :EOF
You would need to change the values assigned to sourcedir and destdir to suit your circumstances. The listing uses a setting that suits my system.
I deliberately include spaces in names to ensure that the spaces are processed correctly.
I used a file named q65417881.txt containing your data for my testing.
The line data read from the file is assigned to %%a is assigned to and number[!count!] alternately. The data is retained in these arrays for use by further processing.
[Edited to include conversion of spaces within names to dashes]
If I understand correctly, you want to precede every second line with Number: + SPACE and every other line with Name: + SPACE. For this you do not need to store each line in a variable first, you can use a single for /F loop lo read the file line by line and process every line individually. There are two possibilities:
Temporarily precede every line with a line number plus : using findstr /N:
#echo off
rem // Loop through lines and precede each with line number plus `:`:
for /F "tokens=1* delims=:" %%K in ('findstr /N "^" "Test1.txt"') do (
rem // Calculate remainder of division by two:
set /A "MOD=%%K%%2" 2> nul
rem // Toggle delayed expansion to avoid issues with `!`:
setlocal EnableDelayedExpansion
rem // Conditionally return line string with adequate prefix:
if !MOD! neq 0 (
endlocal & echo Name: %%L
) else (
endlocal & echo Number: %%L
)
)
This will fail when a line begins with the a :.
Check whether numeric representation of current line string is greater than 0:
#echo off
rem // Loop through (non-empty) lines:
for /F "usebackq delims=" %%L in ("Test1.txt") do (
rem // Determine numeric representation of current line string:
set /A "NUM=%%L" 2> nul
rem // Toggle delayed expansion to avoid issues with `!`:
setlocal EnableDelayedExpansion
rem // Conditionally return line string with adequate prefix:
if !NUM! equ 0 (
endlocal & echo Name: %%L
) else (
endlocal & echo Number: %%L
)
)
This fails when a name begins with numerals and/or when a numeric line is 0.
And just for the sake of posting something different:
#SetLocal EnableExtensions DisableDelayedExpansion & (Set LF=^
% 0x0A %
) & For /F %%G In ('Copy /Z "%~f0" NUL') Do #Set "CR=%%G"
#For /F "Tokens=1,2* Delims=:" %%G In ('%__AppDir__%cmd.exe /D/V/C ^
"%__AppDir__%findstr.exe /NR "^[a-Z]*!CR!!LF![0123456789]" "Test1?.txt" 2>NUL"
') Do #(SetLocal EnableDelayedExpansion
(Set /P "=Name: %%I!CR!!LF!Number: " 0<NUL & Set "_="
For /F Delims^=^ EOL^= %%J In ('%__AppDir__%more.com +%%H "%%G"') Do #(
If Not Defined _ Set "_=_" & Echo %%J)) 1>"%%I.txt" & EndLocal)
This file should be run with the Test1.txt file in the current working directory. It is important that along side Test1.txt, there are no other .txt files with the same basename followed by one other character, (for example Test1a.txt or Test12.txt). Should you wish to change your filename, just remember that you must suffix its basename in the above code with a ? character, (e.g. MyTextFile.log ⇒ MyTextFile?.log).
I had the rare opportunity to verify that this script worked against the following example Test1.txt file:
Beth
1234567891
Jay
2134456544
Bob
2137856514
Jimmy
4574459540
Mary
3734756547
Gemma
6938456114
Albert
0134056504
I know batch isn't the best vehicle for this but my requirements dictate that I keep it.
I have text that looks like the following (it also has blank lines):
Line AAA text
Line BBB text
! ***### START
Body text here
! ***### END
Line XXX
Line YYY
!Comment Line etc
I want to remove the ! ***### START and END lines and everything in between and then save over the original file.
I found and modified the code below but it strips out my blank lines and the ! characters.
#echo off
setlocal enabledelayedexpansion
set "sourceFile=c:\temp\startfile.txt"
set "tempFile=c:\temp\tempfile.txt"
set "StartPhrase=! ***### START"
set "EndPhrase=! ***### END"
set /a lineNum=0
REM check file for search phrase, store line as refLine
FOR /F "delims=" %%i IN (%sourceFile%) DO (
set /a lineNum+=1
echo !lineNum! = "%%i"
if "%%i" == "%StartPhrase%" (
echo Found "%StartPhrase%" on line !lineNum!
set /a StartrefLine=!lineNum!
)
if "%%i" == "%EndPhrase%" (
echo Found "%EndPhrase%" on line !lineNum!
set /a EndrefLine=!lineNum!
)
)
REM make backup
copy "%sourceFile%" "%sourceFile%-%DATE:/=-% %TIME::=-%.txt"
echo. 2>%tempFile%
REM Rewrite file
set /a lineNum=0
set /a lowEnd=%StartrefLine%
echo "Set low end to %lowEnd%"
set /a highEnd=%EndrefLine%
echo "Set high end to %highEnd%"
FOR /F "delims=" %%i IN (%sourceFile%) DO (
set /a lineNum+=1
if !lineNum! GTR %lowEnd% (
if !lineNum! LSS %highEnd% (
echo "Skipping line #!lineNum!"
)
)
if !lineNum! LSS %lowEnd% (
echo "Writing Line !lineNum! %%i to temp file..."
echo %%i >> %tempFile%
)
if !lineNum! GTR %highEnd% (
echo "Writing Line !lineNum! %%i to temp file..."
echo %%i >> %tempFile%
)
)
REM get target filename only
for %%F in ("%sourceFile%") do set fname=%%~nxF
REM del original file and rename tempfile
echo "Deleting original file..."
echo Y | del "%sourceFile%"
echo "Renaming %tempFile% to %fname%"
ren "%tempFile%" "%fname%"
A possible and quite simple way is to let the particular line markers toggle a flag that indicates whether or not the currently iterated line is to be output:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_FILE=C:\TEMP\startfile.txt"
set "_TMPF=%TEMP%\%~n0_%RANDOM%.tmp"
set "_START=! ***### START"
set "_END=! ***### END"
rem // Initialise flag:
set "FLAG=#"
rem // Write to temporary file:
> "%_TMPF%" (
rem /* Loop through lines of input file; `findstr` precedes each line with
rem line number plus `:`, so they do not appear empty to `for /F`: */
for /F "delims=" %%L in ('findstr /N "^" "%_FILE%"') do (
rem // Store current line string (with line number prefix) to variable:
set "LINE=%%L"
rem // Toggle delayed expansion to avoid loss of `!`:
setlocal EnableDelayedExpansion
rem // Remove line number prefix to retrieve original line string:
set "LINE=!LINE:*:=!"
rem // Check contents of current line:
if "!LINE!"=="!_START!" (
endlocal & set "FLAG="
) else if "!LINE!"=="!_END!" (
endlocal & set "FLAG=#"
) else (
rem // Check state of flag for outputting:
if defined FLAG echo(!LINE!
endlocal
)
)
) && (
rem // Move temporary file onto target file:
move /Y "%_TMPF%" "%_FILE%"
)
endlocal
exit /B
This task could be done with worst script interpreter available for this task with following code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFile=C:\Temp\startfile.txt"
if not exist "%SourceFile%" goto :EOF
set "TempFile=%SourceFile%.tmp"
set "PrintLines=1"
(for /F "delims=" %%I in ('%SystemRoot%\System32\findstr.exe /N /R "^" "%SourceFile%"') do (
set "Line=%%I"
setlocal EnableDelayedExpansion
if defined PrintLines (
if not "!Line: ***### START=!" == "!Line!" (
endlocal
set "PrintLines="
) else (
echo(!Line:*:=!
endlocal
)
) else (
if not "!Line: ***### END=!" == "!Line!" (
endlocal
set "PrintLines=1"
) else endlocal
)
))>"%TempFile%"
move /Y "%TempFile%" "%SourceFile%"
if exist "%TempFile%" del "%TempFile%"
endlocal
for /F results in ignoring all empty lines. For that reason command findstr is used to output all lines with line number and colon at beginning in a separate command process started with %ComSpec% /c in background. So there is no empty line anymore in captured output of findstr.
Each captured line starting with a digit in range 1 to 9 is assigned completely to the loop variable I because of using option delims= to define an empty list of string delimiters to disable the default line splitting behavior on normal spaces and horizontal tabs.
The line with line number and colon at beginning is assigned to the environment variable Line while delayed environment variable expansion is disabled. This is important as otherwise the Windows command processor cmd.exe processing the batch file would parse the command line set "Line=%%I" after having replaced %%I by current line with enabled delayed expansion and would interpret each ! as beginning/end of a delayed expanded environment variable.
Then the delayed expansion is enabled for further processing the line depending on printing lines currently enabled as by default until a line is found containing the string ***### START. Next the environment variable PrintLines is undefined until a line is found containing the string ***### END on which PrintLines is defined again for the following lines.
Please read second half of this answer for details about the commands SETLOCAL and ENDLOCAL.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
del /?
echo /?
endlocal /?
findstr /?
for /?
if /?
move /?
set /?
setlocal /?
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q65218525.txt"
SET "outfile=%destdir%\outfile.txt"
SET "blockstart=! ***### START"
SET "blockend=! ***### END"
SET "repro=Y"
(
FOR /f "tokens=1*delims=:" %%a IN ('findstr /n /r ".*" "%filename1%"') DO (
IF /i "%%b"=="%blockstart%" SET "repro="
IF /i "%%b"=="%blockend%" (SET "repro=Y") ELSE (IF DEFINED repro IF "%%b"=="" (ECHO.) ELSE (ECHO %%b))
)
)>"%outfile%"
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances. The listing uses a setting that suits my system.
I used a file named q65218525.txt containing your data for my testing.
Produces the file defined as %outfile%
Since your code saves the original file under a new name and creates a new file with the old name but your requirement seems to be to simply overwrite the old file, I'll leave that part as an exercise.
First, define the strings involved, and a flag (which I've called repro) which is initialised to reproduce the data.
Then use findstr with the /N option to prefix each line, including blank lines, with number: which is then parsed by the for/r to put the number in %%a and the text in %%b.
Check %%b for the target strings and frob the repro flag as appropriate to select whether to reproduce the line read or not.
Another way to do this would be using PowerShell. Invoke it from the command line or a .bat file script using:
powershell -NoLogo -NoProfile -File '.\Slice-File.ps1'
=== Slice-File.ps1
$SourceFile = 'C:\src\t\Slice-File.txt'
$TempFile = New-TemporaryFile
$WriteIt = $true
Get-Content -Path '.\Slice-File.txt' |
ForEach-Object {
if ($_ -eq '! ***### START') { $WriteIt = $false }
if ($WriteIt) { $_ }
if ($_ -eq '! ***### END') { $WriteIt = $true }
} |
Out-File -FilePath $TempFile -Encoding ascii
Remove-Item -Path $SourceFile
Move-Item -Path $TempFile -Destination $SourceFile
So I need a code that will take a text file (we'll cal it list.txt) and turn every line into a variable.
To give some context, I have some file names listed in list.txt, which adds and deletes file names occasionally by user request. I want the user of this code to be able to select which document they'd like to open using variables.
For example, if list.txt looks like this
list.txt
loading.txt
test1.txt
test2.txt
test3.txt
test4.txt
Then I'd like an automatic variable for every .txt listed. I then would add a simple if statement to open the file matched with the variable.
Am I making this too complicated for myself or is this the only way to do this?
EDIT:
I am not attempting something like this:
type list.txt
echo.
echo.
set /p GROUPSELECT= Please type out the FULL name of the group listed:
CD %grouplist%
type %GROUPSELECT%
It will display the file contents, and then display the specific file chosen by the input. I'd think that the variable might be easier to do more with later though, just a thought.
Edit2
I tried this:
#Echo OFF
FOR /F "Usebackq Delims=" %%a IN (
"list.txt"
) DO (
set jim=%%a
)
echo %jim%
PAUSE
%jim% will only be the last line in the text file, so how do I make the next step into making them all different?
Give this a try. I have commented each line of code that should explain what it is doing. Let me know if you need any further explanation.
#echo off
REM FOR commnd is parsing the output of the FINDSTR commands.
REM First FINDSTR command is finding non empty lines in the file
REM Second Findstr command is assigning a number to each line of the file
REM The output is split into two tokens and the number is assigned to %%G and the line of the file to %%H
for /F "tokens=1* delims=:" %%G IN ('findstr /V "^$" list.txt ^|findstr /N ".*"') DO (
REM create a variable of the lines in the file
set "file%%G=%%H"
REM Create a menu of the lines in the file
echo %%G %%H
REM Get the number of lines in the output
set "num=%%G"
)
REM Ask user to chose a number
set /P "filenum=Chose a file number 1 to %num%:"
REM Need to enable delayed expansion to use array variables
setlocal enabledelayedexpansion
REM Check if they type in a correct number and display the file
IF DEFINED file%filenum% type !file%filenum%!
endlocal
pause
Is this the sort of thing you're looking for?
#For /F "Delims==" %%# In ('Set # 2^>Nul')Do #Set "%%#="
#For /F Tokens^=1*Delims^=[]^ EOL^= %%# In ('Type "file.txt"^|Find /V /N ""'
)Do #Set "#%%#=%%$"&Echo( %%#. %%$
:Opt
#Echo(
#Set /P "Opt=Choose a document to open>"
#Set #|Findstr /B "#%Opt%=">Nul||GoTo :Opt
#Call Start "" "%%#%Opt%%%"
Just change the name of the text file containing your list on line 2 as needed.
#TheBoy your question is confusingly framed. If you DO NOT want the example you put in the edit, then can you better explain what you DO want??
Do you want to say iterate over the list file, and create a choice screen?
#(SETLOCAL EnableDelayedExpansion
ECHO OFF
SET "_ChoiceList_File=C:\Admin\ChoiceFile.txt"
REM Full Character List to populate Choices
SET "_CharList=0 1 2 3 4 5 6 7 8 9 A B C D E F N X"
)
CALL :Main
( ENDLOCAL
EXIT /B 0
)
:Main
REM Now we can Do Our Choices btu lets do it in a Sub Function.
CALL :MakeChoice _ChoiceResult
ECHO.
ECHO The Index Chosen Was: %_Chosen%
ECHO The Result Matched is: "%_ChoiceResult%"
REM ECHO Here you output "%_ChoiceResult%"
TYPE "%_ChoiceResult%"
GOTO :EOF
:MakeChoice
cls
color 1A
SET %~1="
SET "_Choices="
SET "_Chosen="
SET "_Amount="
SET "_Choice.17.Value=Next Set!"
SET "_Choice.18.Value=EXIT!"
SET "_Choice_Show_Next="
echo. Pick a File:
echo.========================
REM Create Numbered Array of Choices and output Choices to the Screen
FOR /F "tokens=* usebackq" %%A IN ("%_ChoiceList_File%") DO (
SET /A "_Amount+=1"
SET "_Choice.!_Amount!.Value=%%A"
IF !_Amount! EQU 16 (
SET /A "_Amount+=2"
CALL :MakeChoice "%~1"
IF DEFINED _Chosen (
IF !_Chosen! NEQ 17 (
REM IF !_Chosen! NEQ 18 (
GOTO :EOF
REM )
)
SET "_Amount="
SET "_Chosen="
)
)
)
IF NOT DEFINED _Chosen (
SET /A "_Amount+=1"
SET "_Choice.!_Amount!.Value=!"
SET /A "_Amount+=1"
SET "_Choice.!_Amount!.Value=EXIT!"
CALL :MakeChoice "%~1"
)
GOTO :EOF
:MakeChoice
CLS
ECHO.
SET "_Temp="
SET "_Choices="
SET /A "_Skipline= !_Amount! - 1"
REM Create Choice List to Display only the choices needed.
FOR %%A IN (%_CharList%) DO (
SET /A "_Temp+=1"
IF !_Temp! LEQ !_Amount! (
IF !_Temp! EQU !_Skipline! (
ECHO.
ECHO.=============================
)
IF DEFINED _Choice.!_Temp!.Value (
SET "_Choices=!_Choices!%%A"
CALL ECHO. %%A : %%_Choice.!_Temp!.Value%%
)
)
)
ECHO.
CHOICE /C !_Choices! /N /M "What File do you want to choose? "
SET "_Chosen=%ERRORLEVEL%"
SET "%~1=!_Choice.%_Chosen%.Value!"
GOTO :EOF
)
You can try this:
#echo off
setlocal enabledelayedexpansion
set jim=
for /f "delims=] tokens=1*" %%a in ('find /v /n "" ^<list.txt') do (
set jim=!jim! %%b
)
echo Select a file from !jim!
set /p file=
type !file!
pause
This will read all lines from the list.txt and return them within a variable !jim!.
I want to do this:
set kommune
FOR /F "tokens=* delims=" %%x in (DBLib.txt) DO (
CALL :decryptLine "%%x"
)
GOTO:eof
:decryptLine
for /f "tokens=1,* delims==" %%a in ("%~1") do set argument=%%a & set value=%%b
set "argument=%argument:~0,-2%"
set "value=%value:~1%"
call:updateVar "%argument%" "%value%"
GOTO:EOF
:updateVar
IF "%~1" == "KommuneNavn" (
ECHO "%~2"
ECHO "KommuneNavn"
set kommune=%~2
ECHO kommune = "%kommune%" testhest
)
What it outputs:
"ABC Test Kommune"
"KommuneNavn"
"kommune = "" testhest"
How do i copy the value of the secont argument to the Variable "kommune"? And Echo it?
Edit 1: updated to exact code. "inside IF"
#ECHO OFF
SETLOCAL
set kommune
FOR /F "tokens=* delims=" %%x in (q27922463.txt) DO (
CALL :decryptLine "%%x"
)
GOTO:eof
:decryptLine
for /f "tokens=1,* delims==" %%a in ("%~1") do set "argument=%%a" & set "value=%%b"
set "argument=%argument:~0,-2%"
set "value=%value:~1%"
call:updateVar "%argument%" "%value%"
GOTO:EOF
:updateVar
IF "%~1" == "KommuneNavn" (
ECHO "%~2"
ECHO "KommuneNavn"
set kommune=%~2
CALL ECHO kommune = "%%kommune%%" testhest
)
GOTO :eof
Critical point: You haven't shown us the content of your file, so we have to construct it: and I've changed the filename to suit my system (q27922463.txt)
contents of q27922463.txt
KommuneNavnxy=yourvalue
output generated:
"ourvalue"
"KommuneNavn"
kommune = "ourvalue" testhest
Note the positioning of the quotes in the set assignments. Batch is sensitive to spaces in a SET statement. SET FLAG = N sets a variable named "FLAGSpace" to a value of "SpaceN"
So, %%a becomes KommuneNavnxy, is assigned to argument, and the last 2 characters are removed, making KommuneNavn
Similarly, %%b gets yourvalue, you remove the first and make ourvalue
Since the string kommune is set within the code block of the if statement, you need to use call echo %%var%% to display it (one of several ways).
When running the following code in a windows batch file everything works aside from the string containing the asterisk, which is skipped. Checking the passed parameters by number (i.e. echo(%~6) I can see the asterisk - it's only when passed to the FOR loop that I have an issue:
#echo off
setlocal enableextensions enabledelayedexpansion
call:Concat cmd "this is a demo" " of concat functionality." " Hopefully it will work;" " but it doesn't when I pass an" " * asterisk" " character"
echo !cmd!
#goto:end
#goto:eof
:Concat
::Concatenates a given list of strings without including their quotes
::1 - output variable
::2* - strings to concat
echo(%*
set /a xx=0
set Concat_tempFlag=0
set Concat_temp=
for %%A in (%*) do (
set /a xx=!xx!+1
echo !xx! - %%A
if !Concat_tempFlag!==1 (
set Concat_temp=!Concat_temp!%%~A
) else (
set Concat_tempFlag=1
)
)
set "%~1="%Concat_temp%""
#goto:eof
:End
echo(Bye
exit /b 0
I've attempted for /F (tokens=*) %%A in ('echo(%*') do ( as suggested here: Batch FOR loop with asterisk (and variations thereof) but with no luck. Any ideas? Thanks in advance.
Found the solution here: I need to match or replace an asterisk * in a batch environmental variable using only native Windows commands. Is this possible?
Full code below:
#echo off
setlocal enableextensions enabledelayedexpansion
set DEFAULT_AsteriskMarker=_xAsteriskMarkerx_
call:Concat cmd "this is a demo" " of concat functionality." " Hopefully it will work;" " but it doesn't when I pass an" " * asterisk" " character"
echo !cmd!
#goto:end
#goto:eof
:Concat
::Concatenates a given list of strings without including their quotes
::1 - output variable
::2* - strings to concat
set Concat_StringsToConcat=%*
echo(%Concat_StringsToConcat%
call:AsteriskFix Concat_StringsToConcat
set /a xx=0
set Concat_tempFlag=0
set Concat_temp=
for %%A in (%Concat_StringsToConcat%) do (
set /a xx=!xx!+1
echo !xx! - %%A
if !Concat_tempFlag!==1 (
set Concat_temp=!Concat_temp!%%~A
) else (
set Concat_tempFlag=1
)
)
set "%~1="!Concat_temp:%DEFAULT_AsteriskMarker%=*!"
#goto:eof
:AsteriskFix
::https://stackoverflow.com/questions/11685375/i-need-to-match-or-replace-an-asterisk-in-a-batch-environmental-variable-using
set AsteriskFix_temp=!%~1!
if "%~2"=="" (
set AsteriskFix_marker=%DEFAULT_AsteriskMarker%
) else (
set AsteriskFix_marker=%~2
)
call:StrLen AsteriskFix_temp AsteriskFix_len
for /l %%x in (0,1,%AsteriskFix_len%) do if not "!AsteriskFix_temp:~%%x,1!"=="" if "!AsteriskFix_temp:~%%x,1!"=="*" (
set /a AsteriskFix_plusone=%%x+1
for /l %%y in (!AsteriskFix_plusone!, 1, !AsteriskFix_plusone!) do (
set AsteriskFix_temp=!AsteriskFix_temp:~0,%%x!%AsteriskFix_marker%!AsteriskFix_temp:~%%y!
)
)
set "%~1=!AsteriskFix_temp!"
#goto:eof
:StrLen
::http://www.dostips.com/DtCodeCmdLib.php#strLen
set "StrLen_str=A!%~1!" &:: keep the A up front to ensure we get the length and not the upper bound
::it also avoids trouble in case of empty string
set "StrLen_len=0"
for /L %%A in (12,-1,0) do (
set /a "StrLen_len|=1<<%%A"
for %%B in (!StrLen_len!) do if "!StrLen_str:~%%B,1!"=="" set /a "StrLen_len&=~1<<%%A"
)
IF "%~2" NEQ "" SET /a %~2=%StrLen_len%
#goto:eof
:End
echo(Bye
exit /b 0
Thanks to James K
The link you provided leads to the right answer:
There is no way to preserve an asterisk (nor a question mark) in the set of a normal (no /F option) FOR command (they are always changed to file names); you need to separate the parameters in a FOR /F command. If you also want to process each parameter in a FOR loop, then the second FOR can NOT be in the same context, so you must CALL a subroutine to change the context