Variable outside for /f command keeps getting reset - batch-file

In the following code, it seems that the set /A lcnt=3 at the top of the file is executed each time that the for /f command just below the REM #1 is executed.
I guess I don't understand the flow of execution. I thought it just runs from top to bottom, barring any gotos.
My script:
echo off
REm Why is the following set command executed each time
REM in the below "processToken section"?
set /A lcnt=3
cd c:\download
REM ___ input file _____
REm Moe Larry Curly
REM Manny Moe Jack
REM ___ echo output ____
REM 4
REM 3
REM 5
REM 4
REM 6
REM 5
REM 4
REM 3
REM 5
REM 4
REM 6
REM 5
REm #1
for /f "tokens=* delims= " %%f in ('type test_list.txt') do (
set line=%%f
call :processToken
)
pause
goto :eof
:processToken
SETLOCAL EnableDelayedExpansion
for /f "tokens=1* delims= " %%a in ("%line%") do (
set /A lcnt+=1
echo !lcnt!
echo %lcnt%
set line=%%b
)
if not "%line%" == "" goto :processToken
goto :eof
pause

I'm not sure what you're trying to achieve because your question does not provide that information.
Here therefore is some example code which may help:
#Echo Off
SetLocal EnableDelayedExpansion
Set "x=0"
For /F "UseBackQDelims=" %%A in ("C:\download\test_list.txt") Do (Set/A x+=1
Set "y=0"
For %%B In (%%A) Do (Set/A y+=1
Set "line!x!str!y!=%%~B")
Echo line!x! has !y! space separated strings)
Set line 2>Nul
Pause

Related

Batch Script Variables - Pull from a single line of a text file with multiple lines of variable options

I'm trying to create a batch file that the user can use to connect with SCCM and RDP to PCs that are constantly connected to. I can do this easily with writing out the script for each PC but I would like to do this in a way that I have a text file with variables as I would do with a LOOP but I don't need a LOOP, I need to be able to select a single line of the text file.
Currently I have a list of options and I manually edit the script file with the options and the user selects a number to select the name but I need to remove all script so that the user doesn't accidentally modify the script, only the variables.
Sample text file - (Store user entered variables for both SCCM and RDP)
Variable1 Variable2 Variable3 Variable4
Description1 ComputerName1 ComputerUser1 ComputerPassword1
Description2 ComputerName2 ComputerUser2 ComputerPassword2
Description3 ComputerName3 ComputerUser3 ComputerPassword3
Description4 ComputerName4 ComputerUser4 ComputerPassword4
Description5 ComputerName5 ComputerUser5 ComputerPassword5
Description6 ComputerName6 ComputerUser6 ComputerPassword6
Sample SCCM Batch script -
(SCCM command line interface only allows computer name so I'd only be able to pull the name but I still want a single text file for both SCCM and RDP connections)
Variable1's listed from text file -
Description1
Description2
Description3
Description4
Description5
Description6
Make a selection: ((User enters Variable1))
sccm\CmRcViewer.exe "<variable2>" <-------from a specific line a user selects
Sample RDP Batch script - (I use the cmdkey to store the user/pass since mstsc command line interface only allows the name unless I do this first)
Variable1's listed from text file -
Description1
Description2
Description3
Description4
Description5
Description6
Make a selection: ((User enters Variable1))
cmdkey /generic:"<variable2>" /user:"<variable3>" /pass:"<variable4>" <-------from a specific line a user selects
mstsc /v:"<variable2>" /f <-------from a specific line a user selects
Any assistance is greatly appreciated. As a disclaimer, this is only being used by those in IT who has a decent knowledge of batch scripts, just trying to make it a tad easier to get to our PCs we are constantly accessing and those users we are constantly helping remotely...
This is a line selector I've made previously that builds an Array containing the value of each Line and allows scrolling and selection of the value via the choice command.
The :Load and :Extract labels are where the functions most relevant to your needs reside.
EDIT:
The stripped down components modified for just the output you seek - Using the safer form of input (Choice Command). Note that if the number of options exceeds 9, Set /P will need to be used - though input should be validated.
#Echo Off & Setlocal EnableDelayedExpansion
Set "lines=0"
Set "Options=E"
For /f "Skip=1 Tokens=* Delims=" %%A in (%~dp0\Choices.txt) do (
Set /A lines+=1
Set "line[!lines!]=%%A"
Set "Options=!Options!!lines!"
)
:extract
Cls
For /F "Tokens=1,2 Delims==" %%A in ('Set line[') Do (
Set "Option=%%~A"
Set "Option=!Option:line=!"
Echo !Option! %%B
)
For /F "Delims=" %%C in ('Choice /N /C %Options%') Do (
If "%%C" == "E" (Endlocal & Exit /B 0)
For /F "Tokens=2,3,4 Delims= " %%G in ("!line[%%C]!") Do cmdkey /generic:"%%~G" /user:"%%~H" /pass:"%%~I" & mstsc /v:"%%~G" /f
)
Goto :extract
An example of validating input if using Set /P
Set /P "INPUT=Selection: "
For /F "Delims=" %%C in ("!Input!") Do (
echo.%%C| findstr /R "[^0-9]" >nul 2>nul && Goto :extract
IF "%%C" == "0" (Endlocal & Exit /B) Else IF "%%C" GTR "%lines%" Goto :extract
For /F "Tokens=2,3,4 Delims= " %%G in ("!line[%%C]!") Do cmdkey /generic:"%%~G" /user:"%%~H" /pass:"%%~I" & mstsc /v:"%%~G" /f
)
Original
#Echo off & CD "%~dp0"
TITLE %~n0 & Setlocal
%= Remark =%
(Set LF=^
%= NewLine variable to split set /p input line =%)
::: / Creates variable /AE = Ascii-27 escape code.
::: - http://www.dostips.com/forum/viewtopic.php?t=1733
::: - https://stackoverflow.com/a/34923514/12343998
:::
::: - /AE can be used with and without DelayedExpansion.
Setlocal
For /F "tokens=2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
Endlocal
Set "/AE=%%a"
)
::: \
%= create blank batch file to store and Selectively retieve variables with =%
If not Exist "inputURLlog.log" (Break>inputURLlog.log & Goto :main)
For %%A in ( "%/AE%[36m[%/AE%[34mN%/AE%[36m]ew" , "[%/AE%[34mL%/AE%[36m]oad%/AE%[0m")Do Echo.%%~A
Choice /N /C nl >nul
If errorlevel 2 (Goto :load)
Goto :Main
:Input <VarName>
Set "variable=%~1"
Setlocal EnableDelayedExpansion
:Validate
%= allow input of variable, test input, store for reuse. =%
Echo(%/AE%[35m
Set /P "input=!variable!!LF!%/AE%[36m{> %/AE%[33m"
IF "!input!"=="" (
Echo(%/AE%[31m!variable! required.
Goto :Validate
)
If "!input!"=="" (Echo(%/AE%[31m!variable! required. & Goto :Validate)
IF /I "!input!"=="load" (Goto :load)
%= Url Validation - Optional =%
(ping !input!)>nul || (Echo Invalid url & Endlocal & Goto :main)
ECHO(!input!>>inputURLlog.log
Endlocal
Exit /B
:main
Call :Input Url
Goto :main
:load
Setlocal EnableDelayedExpansion
Set lines=0
For /f "Tokens=* Delims=" %%A in (inputURLlog.log) do (
Set /A lines+=1
Set "line[!lines!]=%%A"
)
REM Set "#=%lines%" & REM start from newest entry
Set "#=1" & REM start from oldest entry
Echo %#%
:extract
For %%A in (!#!) do (
Cls
Title Option %%A of !lines!
Echo(Url: !line[%%A]!
For %%B in ("%/AE%[36m[%/AE%[34mS%/AE%[36m]elect" "[%/AE%[34mN%/AE%[36m]ext" "[%/AE%[34mL%/AE%[36m]ast%/AE%[0m")Do Echo.%%~B
Choice /N /C LNS /M ""
If "!errorlevel!"=="3" (Set "Url=!line[%%A]!" & Goto :Selected)
If "!errorlevel!"=="2" (IF not !#! GEQ !lines! (Set /A #+=1) Else (Set "#=1"))
If "!errorlevel!"=="1" (IF not !#! LEQ 1 (Set /A #-=1) Else (Set "#=%lines%"))
)
Goto :extract
%= Demonstrate that variable has been reloaded =%
:Selected
Echo( Selected Url = !Url!
Pause >nul
#echo off
setlocal enabledelayedexpansion
set x=0
for /f "skip=1 tokens=1-4" %%i in (%~dp0\Choices.txt) do (
call set /a x+=1
call set item.%%x%%.1=%%i
call set item.%%x%%.2=%%j
call set item.%%x%%.3=%%k
call set item.%%x%%.4=%%l
)
for /l %%i in (1,1,%x%) do (
call echo %%i. !item.%%i.1!
)
echo. & set /p sel=Enter Selection:
cmdkey /generic:"!item.%sel%.2!>" /user:"!item.%sel%.3!" /pass:"!item.%sel%.4!"
mstsc /v:"!item.%sel%.2!" /f

Variables not incrementing within a batch file

So I am trying to create a file that will read a text file called saves. In saves I want it to check up to 5 time for 1:, 2:, 3: ,4:, and 5:. The issue is that when I run this for loop to check the file 5 times it always outputs the same thing and no matter what will say there are no saves. Any help or advice is much appreciated.
#ECHO off
SETLOCAL EnableDelayedExpansion
SET test=0
FOR /L %%i IN (1,1,5) DO (
FINDSTR %%i: Saves.txt >NUL && SET /a %test%+1
ECHO %test%
)
IF %test% EQU 0 ECHO There are no saves. & GOTO :end
IF %test% GTR 0 ECHO There are saves.
:END
PAUSE
You are not using the SET command correctly and you need to use delayed expansion to display the variable correctly when inside a parenthesized code block.
#ECHO off
SETLOCAL EnableDelayedExpansion
SET test=0
FOR /L %%i IN (1,1,5) DO (
FINDSTR /B %%i: Saves.txt >NUL && SET /a test+=1
ECHO !test!
)
IF %test% EQU 0 ECHO There are no saves. & GOTO :end
IF %test% GTR 0 ECHO There are saves.
:END
PAUSE
An easier option would be.
FINDSTR /B "1: 2: 3: 4: 5:" Saves.txt >NUL 2>&1 && (ECHO There are saves.) || (ECHO There are no saves.)
If all your lines begin with a number and colon then you can just do this.
FOR /F "tokens=1 delims=:" %%G IN (saves.txt) do set numsaves=%%G

How can we split string using windows bat

How can we split string using windows bat script?
for below .bat code snippet
#echo off & setlocal EnableDelayedExpansion
set j=0
for /f "delims=""" %%i in (config.ini) do (
set /a j+=1
set con!j!=%%i
call set a=%%con!j!%%
echo !a!
(echo !a!|findstr "^#">nul 2>nul && (
rem mkdir !a!
) || (
echo +)
rem for /f "tokens=2" %%k in(config.ini) do echo %%k
)
)
pause
below config file
Q
What's wrong when I del rem at the begin of rem for /f "tokens=2" %%k in(config.ini) do echo %%k
How can I get the /path/to/case and value as a pair?
for /f xxxx in (testconfig.ini) do (set a=/path/to/case1 set b=vaule1)
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q43407067.txt"
set j=0
for /f "delims=""" %%i in (%filename1%) do (
set /a j+=1
set con!j!=%%i
call set a=%%con!j!%%
echo !a! SHOULD BE EQUAL TO %%i
(echo !a!|findstr "^#">nul 2>nul && (
echo mkdir !a!
) || (
echo +)
for /f "tokens=2" %%k IN ("%%i") do echo "%%k"
for /f "tokens=1,2" %%j IN ("%%i") do echo "%%j" and "%%k"
)
)
ECHO ----------------------------
SET con
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
I used a file named q43407067.txt containing your data for my testing.
(These are setting that suit my system)
SO - to address your problems:
because the ) on that line closes the ( on the previous. The ) on that line closes the ( on the one prior. (I changed the rem to an echo so that the code would produce something visible) The first ( on the (echo !a! line is closed by the ) on the line following the (now) two for /f commands. and the ( on the for..%%i..do( is closed by the final ) before the echo -----
You can't delete that ) because it's participating in a parenthesis-pair.
You need a space between the in and the (.
I've shown a way. See for /?|more from the prompt for documentation (or many articles here on SO)
In your code, !a! is the same as %%i - so I've no idea why you are conducting all the gymnastics - doubtless to present a minimal example showing the problem.
Note that since the default delimiters include Space then if any line contains a space in the /path/to/case or value then you'll have to re-engineer the approach.
I' not sure if I understand what exactly it is you need, so what follows may not suit your needs:
#Echo Off
SetLocal EnableDelayedExpansion
Set "n=0"
For /F "Delims=" %%A In (testConfig.ini) Do (Set "_=%%A"
If "!_:~,1!"=="#" (Set/A "n+=1", "i=0"
Echo=MD %%A
Set "con[!n!]!i!=%%A") Else (For /F "Tokens=1-2" %%B In ('Echo=%%A'
) Do (Set/A "i+=1"
Set "con[!n!]!i!=%%B"&&Set/A "i+=1"&&Set "con[!n!]!i!=%%C")))
Set con[
Timeout -1
GoTo :EOF
remove Echo= on line 6 if you are happy with the output and really want to create those directories

Xor a string in a bat file?

In short I want to give my friend a bat file which does the below (untested)
echo Your mother is so fat
pause
echo the recursive function computing her mass causes a stack overflow
I might copy/paste him the bat file so I don't want the punch line to be ruined. How can I hide the text? I was thinking I can store the string in a variable and before I echo it I should XOR each letter with 32. But I have no idea how to take a string, XOR each letter than echo it to display the joke. How might I hide the text? I could also BASE64 encode/decode it but IDK how to do that either if I am only using a bat file
1) Here's one way to hide the text using mshta as a command line tool (with ascii codes in this case) :
#echo off
mshta vbscript:execute("CreateObject(""Scripting.FileSystemObject"").GetStandardStream(1).Write(Chr(89) & Chr(111)& Chr(117) & Chr(114) & Chr(32) & Chr(109) & Chr(97) & Chr(109) & Chr(97) & Chr(32) ):Close")|more
2) You can use CERTUTIL to encode/decode base64/hex files but it requires a temporary file that can be silently deleted (more info ):
echo 796f7572206d616d6120697320736f20666174>"%temp%\fat.hex"
certutil -decodehex "%temp%\fat.hex" "%temp%\fat.txt" >nul 2>&1
type "%temp%\fat.txt"
del /q /f "%temp%\fat.txt"
3) Dbenham's hex print function
#echo off
setlocal
::Define a Linefeed variable
set LF=^
::above 2 blank lines are critical - do not remove.
::Create a string variable with encoded TABs
call :hexprint "0x790x6f0x750x720x200x6d0x610x6d0x610x200x690x730x200x730x6f0x200x660x610x74" var
echo %var%
exit /b
:hexPrint string [rtnVar]
for /f eol^=^%LF%%LF%^ delims^= %%A in (
'forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(%~1"'
) do if "%~2" neq "" (set %~2=%%A) else echo(%%A
exit /b
4) carlos' genCar function that uses MAKECAB:
#echo off
setlocal
break>fat.txt
for %%# in (121 111 117 114 32 109 97 109 97 32 105 115 32 115 111 32 102 97 116) do (
call :genChar %%#
type %%#.chr>>fat.txt
del /q /f %%#.chr >nul 2>&1
)
type fat.txt
del /q /f fat.txt
goto :eof
:genChar
setlocal
set "USAGE=echo:Usage: Supply an integer 0-255& goto :EOF"
if "%~1" equ "" %USAGE%
set /a "val=%~1" 2>nul
if "%~1" neq "%val%" %USAGE%
if %~1 lss 0 %USAGE%
if %~1 gtr 255 %USAGE%
set tempfile=%~1.tmp
set "options=/d compress=off /d reserveperdatablocksize=26"
if %~1 neq 26 (type nul >"%tempfile%"
makecab %options% /d reserveperfoldersize=%~1 "%tempfile%" %~1.chr >nul
type %~1.chr | (
(for /l %%N in (1 1 38) do pause)>nul&findstr "^">"%tempfile%")
>nul copy /y "%tempfile%" /a %~1.chr /b
del "%tempfile%"
) else (copy /y nul + nul /a 26.chr /a >nul)
endlocal
for more cryptic script you can combine hem.Only MSHTA and MAKECAB solutions will work on every windows machine. FORFILES and CERTUTIL are default form Vista and above I think.It is possible to create a few more examples ...
This is a subject near and dear to my heart because I did something similar in my implementation of the classic Colossal Cave Adventure game as a Windows batch file.
Within the game script I selectively encrypt display text, variable names, and comments. The code to decode the encrypted text is embedded directly within the same script! I write the source code for the game normally, and use braces to denote what portion is to be encrypted. A function within the game is able to generated the encrypted form of itself!
I used a simple symmetric rotation cipher, so really it is more obfuscation than encryption. But that is all that is needed for both the game, and your situation.
I've extracted a simplified version of the routines and provide them below.
The first script is a standalone script that selectively encrypts text within a source file and writes the result to stdout. Simply redirect the output to a new file to get the encrypted version of the file.
selectiveROT13.bat
#echo off
:selectiveROT13 InFile
::
:: Selectively applies the simple "rotate alphabet 13 places" cipher
:: to the contents of file InFile. Only text between curly braces
:: is affected. The affected content can span multiple lines.
::
:: Writes the results to stdout.
:: Percent completion is continuously written to stderr.
::
setlocal enableDelayedExpansion
set "upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set "lower=abcdefghijklmnopqrstuvwxyz"
for /l %%A in (0 1 25) do (
set /a "B=(%%A+13)%%26"
for /f %%B in ("!B!") do (
set "upper!upper:~%%A,1!=!upper:~%%B,1!"
set "lower!lower:~%%A,1!=!lower:~%%B,1!"
)
)
setlocal disableDelayedExpansion
>&2 cls
set "active="
for /f %%N in ('type %1^|find /c /v ""') do set /a "lnCnt=%%N, pct=-1"
for /f "skip=2 tokens=1,* delims=[]" %%a in ('find /v /n "" %1') do (
set "ln=%%b"
setlocal enableDelayedExpansion
set "str=A!ln!"
set "len=0"
for /L %%A in (12,-1,0) do (
set /a "len|=1<<%%A"
for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"
)
set /a len-=1
set rtn=
for /l %%n in (0,1,!len!) do (
set "c=!ln:~%%n,1!"
if "!c!" equ "{" set "active=1"
if "!c!" equ "}" set "active="
if defined active if defined upper!c! for /f %%c in ("!c!") do (
if "!upper:%%c=%%c!" equ "!upper!" (
set "c=!upper%%c!"
) else (
set "c=!lower%%c!"
)
)
set "rtn=!rtn!!c!"
)
echo(!rtn!
for %%A in ("!active!") do (
endlocal
set "active=%%~A"
)
)
exit /b 0
Below is your joke program with a simplified version of the code to decode encrypted text. My original code worked with string variables, but this version works with string literals. The source script is written normally, without encryption. Braces indicate which code is to be encrypted. Besides your joke, I've included documentation and examples to demonstrate some of the features.
joke_src.bat
#echo off
setlocal enableDelayedExpansion
call :init
:: Disable delayed expansion to protect ! within string literals
setlocal disableDelayedExpansion
:: Curly braces are used to denote text that should be encrypted.
:: Encryption can span multiple lines
:: {
:::Line1
:::Line2
:::Line3
:: }
:: I defined a simple SHOW macro that expands to CALL :SHOW
:: Use the %show% macro to display encrypted text.
:: The braces can be hidden by using the undefined %{% & %}% variables
%show% %{%"Quote literals ("") must be doubled ("""") in the source"%}%
:: Here I use a FOR loop to show all encrypted lines within this script
:: that begin with :::
echo(
for /f "delims=: tokens=*" %%A in ('findstr /b ":::" "%~f0"') do %show% "%%A"
echo(
echo And now it is time for a little joke.
echo(
echo Your mother is so fat...
pause
%show% %{%"the recursive function computing her mass causes a stack overflow!"%}%
exit /b
:show Str
::{
:: Applies the simple "rotate alphabet 13 places" cipher to string Str
:: and writes the result to stdout. Consecutive quotes ("") are converted
:: into a single quote (").
::}
setlocal disableDelayedExpansion
set "str=%~1"
setlocal enableDelayedExpansion
set "str=!str:""="!^"
if defined {obfuscated} (
set "len=0"
set "str2=.!str!"
for /L %%A in (12,-1,0) do (
set /a "len|=1<<%%A"
for %%B in (!len!) do if "!str2:~%%B,1!"=="" set /a "len&=~1<<%%A"
)
set /a len-=1
set rtn=
for /l %%n in (0,1,!len!) do (
set "c=!str:~%%n,1!"
if defined {upper}!c! for /f %%c in ("!c!") do (
if "!{upper}:%%c=%%c!" equ "!{upper}!" (
set "c=!{upper}%%c!"
) else (
set "c=!{lower}%%c!"
)
)
set "rtn=!rtn!!c!"
)
) else set "rtn=!str!"
echo(!rtn!
exit /b 0
:init
set "}="
set "{="}
set "{upper}=ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set "{lower}=abcdefghijklmnopqrstuvwxyz"
for /l %%A in (0 1 25) do (
set /a "B=(%%A+13)%%26"
for /f %%B in ("!B!") do (
set "{upper}!{upper}:~%%A,1!=!{upper}:~%%B,1!"
set "{lower}!{lower}:~%%A,1!=!{lower}:~%%B,1!"
)
)
set "{obfuscated}="
set "{obfuscationTest}={A}"
if "!{obfuscationTest}:A=!" equ "!{obfuscationTest}!" set {obfuscated}=1
set "show=call :show"
exit /b
The following command will generate the encrypted version of the script:
selectiveROT13 joke_src.bat >joke.bat
Below is the encrypted form. This is what you would send to your friend. (Without the extra documentation and examples of course)
joke.bat
#echo off
setlocal enableDelayedExpansion
call :init
:: Disable delayed expansion to protect ! within string literals
setlocal disableDelayedExpansion
:: Curly braces are used to denote text that should be encrypted.
:: Encryption can span multiple lines
:: {
:::Yvar1
:::Yvar2
:::Yvar3
:: }
:: I defined a simple SHOW macro that expands to CALL :SHOW
:: Use the %show% macro to display encrypted text.
:: The braces can be hidden by using the undefined %{% & %}% variables
%show% %{%"Dhbgr yvgrenyf ("") zhfg or qbhoyrq ("""") va gur fbhepr"%}%
:: Here I use a FOR loop to show all encrypted lines within this script
:: that begin with :::
echo(
for /f "delims=: tokens=*" %%A in ('findstr /b ":::" "%~f0"') do %show% "%%A"
echo(
echo And now it is time for a little joke.
echo(
echo Your mother is so fat...
pause
%show% %{%"gur erphefvir shapgvba pbzchgvat ure znff pnhfrf n fgnpx biresybj!"%}%
exit /b
:show Str
::{
:: Nccyvrf gur fvzcyr "ebgngr nycunorg 13 cynprf" pvcure gb fgevat Fge
:: naq jevgrf gur erfhyg gb fgqbhg. Pbafrphgvir dhbgrf ("") ner pbairegrq
:: vagb n fvatyr dhbgr (").
::}
setlocal disableDelayedExpansion
set "str=%~1"
setlocal enableDelayedExpansion
set "str=!str:""="!^"
if defined {boshfpngrq} (
set "len=0"
set "str2=.!str!"
for /L %%A in (12,-1,0) do (
set /a "len|=1<<%%A"
for %%B in (!len!) do if "!str2:~%%B,1!"=="" set /a "len&=~1<<%%A"
)
set /a len-=1
set rtn=
for /l %%n in (0,1,!len!) do (
set "c=!str:~%%n,1!"
if defined {hccre}!c! for /f %%c in ("!c!") do (
if "!{hccre}:%%c=%%c!" equ "!{hccre}!" (
set "c=!{hccre}%%c!"
) else (
set "c=!{ybjre}%%c!"
)
)
set "rtn=!rtn!!c!"
)
) else set "rtn=!str!"
echo(!rtn!
exit /b 0
:init
set "}="
set "{="}
set "{hccre}=ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set "{ybjre}=abcdefghijklmnopqrstuvwxyz"
for /l %%A in (0 1 25) do (
set /a "B=(%%A+13)%%26"
for /f %%B in ("!B!") do (
set "{hccre}!{hccre}:~%%A,1!=!{hccre}:~%%B,1!"
set "{ybjre}!{ybjre}:~%%A,1!=!{ybjre}:~%%B,1!"
)
)
set "{boshfpngrq}="
set "{boshfpngvbaGrfg}={N}"
if "!{boshfpngvbaGrfg}:A=!" equ "!{boshfpngvbaGrfg}!" set {boshfpngrq}=1
set "show=call :show"
exit /b
The beauty of this system is that both joke.bat and joke_src.bat generate the exact same output:
Quote literals (") must be doubled ("") in the source
Line1
Line2
Line3
And now it is time for a little joke.
Your mother is so fat...
Press any key to continue . . .
the recursive function computing her mass causes a stack overflow!
Another nice feature is that selectiveROT13.bat can be applied to joke.bat to regenerate the original un-encrypted source.
This code creates a base64 encoded file:
#echo off
set "var=the recursive function computing her mass causes a stack overflow"
>file.tmp echo %var%
certutil -f -encode file.tmp file.tmp2 >nul
echo file.tmp2|find /v "-----" >file.txt
del file.tmp?
pause
and you can use the file like so (adding echo at the start of each line of the encoded file):
#echo off
cls
echo Your mother is so fat
pause
(
echo dGhlIHJlY3Vyc2l2ZSBmdW5jdGlvbiBjb21wdXRpbmcgaGVyIG1hc3MgY2F1c2Vz
echo IGEgc3RhY2sgb3ZlcmZsb3cNCg==
)>file.tmp
certutil -f -decode file.tmp file.txt >nul
timeout /t 2 /nobreak >nul
type file.txt
timeout /t 5 /nobreak >nul
I think you can just replace some chars with others in pure BAT without any temporary files using following string replacing script.
%str:old_char=new_char%
For example, I have defined some encoding and decoding functions. The codes are attached here, and it will print what you want.
#echo off
set str1=Y urke ohtrkmsks kfao
set str2=ohtkrtcursmvtkfuncom nkc epuomngkhtrkeasskcaustskaksoacik vtrfl w
call :decode "%str1%"
call :decode "%str2%"
pause
goto :eof
:decode
set "str=%~1"
set str=%str: =#%
set str=%str:k= %
set str=%str:i=k%
set str=%str:m=i%
set str=%str:e=m%
set str=%str:t=e%
set str=%str:o=t%
set str=%str:#=o%
echo %str%
goto :eof
I also attached the encoding script below.
#echo off
set str1=Your mother is so fat
set str2=the recursive function computing her mass causes a stack overflow
call :encode "%str1%"
call :encode "%str2%"
pause
goto :eof
:encode
set "str=%~1"
set str=%str:o=#%
set str=%str:t=o%
set str=%str:e=t%
set str=%str:m=e%
set str=%str:i=m%
set str=%str:k=i%
set str=%str: =k%
set str=%str:#= %
echo %str%
goto :eof

Batch Files: How to concatenate each line in a text file?

I have a text file with text on each line. I would like to be able to put each line in one long line along with a space. So, if the text file has:
Bob
Jack
Sam
I want the result to be
Bob Jack Sam
Below are two methods that I am working on but I am stuck. Anything in brackets [] means that I know the syntax is completely wrong; I only put it there to show my thought process. The commented sections are just me experimenting and I have left them in case anyone wants to comment on what they would do / why they do what they do.
Method 1:
#echo off
SETLOCAL EnableDelayedExpansion
SET count=1
FOR /F "tokens=* delims= usebackq" %%x IN ("afile.txt") DO (
SET var!count!=%%x
for %%a in (!count!) do (
!var%%a! = !var%%a! & " "
echo !var%%a!
)
SET /a count=!count!+1
echo !count!
)
::echo !var1! !var2! !var3!
start "" firefox.exe !var%%a!-1
ENDLOCAL
::echo "endlocal" %var1% %var2% %var3%
Method 2:
#echo off
SETLOCAL EnableDelayedExpansion
SET count=1
FOR /F "tokens=* delims= usebackq" %%x IN ("afile.txt") DO (
SET var!count!=%%x
call echo %%var!count!%%
SET /a count=!count!+1
echo !count!
)
::echo !var1! !var2! !var3!
start "" firefox.exe ^
[i = 1]
[for i to !count! do (]
call echo %%var!count!%% & " " & " "^
ENDLOCAL
::echo "endlocal" %var1% %var2% %var3%
If you only have three values, you can directly retrieve them from the file
< input.txt (
set /p "line1="
set /p "line2="
set /p "line3="
)
set "var=%line1% %line2% %line3%"
echo("%var%"
If you don't know the number of values, use a for /f command to read the lines and concatenate the contents into a variable.
#echo off
setlocal enableextensions enabledelayedexpansion
set "var="
for /f "usebackq delims=" %%a in ("input.txt") do set "var=!var!%%a "
echo("%var%"
But if the data can contain exclamation signs, the delayed expansion state will remove them (and the text surounded by them). To avoid it, this can be used
#echo off
setlocal enableextensions disabledelayedexpansion
set "var="
for /f "usebackq delims=" %%a in ("input.txt") do (
setlocal enabledelayedexpansion
for /f "tokens=* delims=¬" %%b in ("¬!var!") do endlocal & set "var=%%b%%a "
)
echo("%var%"
where the setlocal/endlocal and the inner for are used to avoid problems with ! character
Or you can try something like this
#echo off
setlocal enableextensions disabledelayedexpansion
for /f "delims=" %%a in ('
"<nul cmd /q /c "for /f "usebackq delims=" %%z in ("input.txt"^) do (set /p ".=%%z "^)""
') do set "var=%%a"
echo("%var%"
It runs a cmd instance to output the input lines as only one output line (<nul set /p is used to ouput the data without line feeds, so all data is in the same line). This is wrapped in a for to retrieve the output inside a variable
Would this work for you?
#echo off
SET var=
SETLOCAL EnableDelayedExpansion
FOR /f %%i in (afile.txt) DO (
SET var=!var!%%i
)
echo !var!
ENDLOCAL
Notice there is a space after the SET var=!var!%%i[Space Here] to separate each word in each row
EDIT:
If you want to display the current value in the loop just print %%i with NO concatenation. After the FOR loop finishes it will print the last value assigned to the variable
#echo off
SET var=
SETLOCAL EnableDelayedExpansion
for /f %%i in (input.txt) do (
SET var=%%i
echo !var!
)
echo %var%
Will print:
Bob
Jack
Sam
Sam
Try this: Post Edited.
#Echo off
Set "File=Recent_Log.txt"
Set "Output=My_Log.txt"
(
For /F %%F in (%File%) Do (
Set /p ".=%%~F "
)
) > "%Output%" < Nul
Goto :Eof
Because this is the first link after a Google search, I post my solution(Windows 7/10 .bat):
for %%f in (h:\blaba\*.*) do (type "%%f" & echo.) >> h:\sfsdf\dd.txt
NOTE: When your directory/filename contains spaces use double quotes.

Resources