What does this batch code exactly do? - batch-file

I just surfed internet to find a function in batch, which colorizes the text. This is the code:
:Color
:: v20 deprecated.
:: Arguments: hexColor text [\n]
:: Supported in windows XP, 7, 8.
:: In XP extended ascii characters are printed as dots.
:: For print quotes, use empty text.
SetLocal enableExtensions EnableDelayedExpansion
Set "Text=%~2"
If Not Defined Text (Set Text=^")
Subst `: "!Temp!" >Nul &`: &Cd \
If Not Exist `.7 (
Echo(|(Pause >Nul &Findstr "^" >`)
Set /P "=." >>` <Nul
For /F "delims=;" %%# In (
'"Prompt $H;&For %%_ In (_) Do Rem"') Do (
Set /P "=%%#%%#%%#" <Nul >`.3
Set /P "=%%#%%#%%#%%#%%#" <Nul >`.5
Set /P "=%%#%%#%%#%%#%%#%%#%%#" <Nul >`.7))
Set /P "LF=" <` &Set "LF=!LF:~0,1!"
For %%# in ("!LF!") Do For %%_ In (
\ / :) Do Set "Text=!Text:%%_=%%~#%%_%%~#!"
For /F delims^=^ eol^= %%# in ("!Text!") Do (
If #==#! SetLocal DisableDelayedExpansion
If \==%%# (Findstr /A:%~1 . \` Nul
Type `.3) Else If /==%%# (Findstr /A:%~1 . /.\` Nul
Type `.5) Else (Echo %%#\..\`>`.dat
Findstr /F:`.dat /A:%~1 .
Type `.7))
If "\n"=="%~3" (Echo()
Goto :Eof
Can anyone please explain how is this working? I would really want to know what does each phrase do and how it participates in printing out color text.
P.S. I know most of the stuff what's happening there, I just don't know how it makes the console print out text in color and why does it create files in %Temp% directory.
I would like for the explanation to be step by step and easy to understand please.
Thank you!

I'm not sure what is going on but the easiest way for me is with powershell:
Put this at the top after #echo off
setlocal EnableDelayedExpansion
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
set "DEL=%%a"
)
rem Prepare a file "X" with only one dot
<nul > X set /p ".=."
(It will create a file "x" that will stick around. Anoying but nothing much.
Then put this at the complete bottom of the script.
:colorEcho
set "param=^%~2" !
set "param=!param:"=\"!"
findstr /p /A:%1 "." "!param!\..\X" nul
<nul set /p ".=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%"
exit /b
Then use this format to make colored text:
call :ColorEcho 81 "text" &echo.
the 81 is the color code for cmd. In the command prompt run color /? and you'll find the color codes there. The first one is the background the second is the text.

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

Typing text with not yet (but will be) defined variables in batch

So i want to create typing text for a Turn Based RPG (in batch), where you have a person controlling almost everything that interacts with the players.
I want it so when everyone's turn is over, it will display what everyone did, but in a dramatic way.
Now some of us know
for %%i in (h e l l o) do (set /p a=%%i<nul & ping 0.0.0.0 -n 2.5>nul 2>&1)
but I want to have a variable do this using
set /p Write=<Write.txt
so i can have something like for %%i in (%write%) do (set /p a=%%i<nul & ping 0.0.0.0 -n 2.5>nul 2>&1)
to make it write one letter at a time.
Thanks!
The Batch file below use an interesting trick I borrowed from this post that convert the Ascii (1-byte) characters into Unicode 2-bytes characters via /U switch of cmd.exe (inserting a zero-byte between characters), and then split the zero-bytes in individual lines via find command:
#echo off
setlocal
echo Hello, World!> Write.txt
for /F %%a in ('echo prompt $H^| cmd') do set "BS=%%a"
for /F "delims=" %%i in ('cmd /D /U /C type Write.txt ^| find /V ""') do (
set /P "=X%BS%%%i" < NUL
ping localhost -n 2 > NUL
)
EDIT: New version added
I modified previous code to show several lines in the right way; it also use JScript's sleep method in order to use variable delay intervals between each character, this point results in an output appearing in a more dramatic way.
#if (#CodeSection == #Batch) #then
#echo off
(
echo Hello, World!
echo The World is ending!
) > Write.txt
for /F %%a in ('echo prompt $H^| cmd') do set "BS=%%a"
for /F "delims=" %%a in (Write.txt) do (
for /F "delims=" %%i in ('cmd /D /U /C set /P "=%%a"^<NUL ^| find /V ""') do (
set /P "=X%BS%%%i" < NUL
REM ping localhost -n 3 > NUL
cscript //nologo //E:JScript "%~F0"
)
echo/
)
goto :EOF
#end
// JScript section: wait a random number of milliseconds between 0 and 300
WScript.Sleep(300*Math.random());
This is a version of Ghost typer that uses a variable, to display text on a screen in a way that a person might type it.
#echo off
:: Ghost typer - variable version
:: shows text in a variable on the screen in a way that a person might type it.
:: Do not use " in the text to be printed, replace them with '
:: Adjust speed variable - higher numbers increase typing speed - default=3
set speed=6
:: backspace variable is used in the printing routine
for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "BS=%%a"
set "line=Your dog was eaten by a red winged dragon!"
call :begin
set "line=Two sloths ate all your chocolate!"
call :begin
set "line=A genie appears, and grants you 4 wishes...."
call :begin
set "line=How many woodchucks does it take?"
call :begin
pause>nul
goto :EOF
:begin
set num=0
:type
call set "letter=%%line:~%num%,1%%"
set "delay=%random%%random%%random%%random%%random%%random%%random%"
set "delay=%delay:~-6%"
if not "%letter%"=="" set /p "=a%bs%%letter%" <nul
for /L %%b in (1,%speed%,%delay%) do rem
if "%letter%"=="" echo.&goto :EOF
set /a num+=1
goto :type
To print the characters one by one of an arbitrary string, you could use the following:
#echo off
rem define string to print:
set "WRITE=Hello world!"
setlocal EnableDelayedExpansion
for /L %%I in (0,1,8191) do (
set "CHAR=!WRITE:~%%I,1!"
rem if "!WRITE:~%%I,2!"=="!CHAR! " set "CHAR=!CHAR! "
if "!CHAR!"=="" goto :SKIP
< nul set /P "DUMMY=!CHAR!"
> nul 2>&1 ping 127.0.0.1 -n 2
)
:SKIP
endlocal
As you will notice, the SPACE within the string in WRITE is not printed, because set /P does not print any (leading) spaces in the prompt string. To work around this, remove the rem in front of the if inside of the for loop. Actually this previews the next character and appends it to the current one in case it is a space, as set /P prints trailing spaces.
#echo off
setlocal enabledelayedexpansion
for /f %%A in ('"prompt $H &echo on &for %%B in (1) do rem"') do set BS=%%A
set /P string=<write.txt
call :StrLen "%string%" _len1
for /L %%A in (0,1,%_len1%) do (
set "substring=!string:~%%A,1!"
set /p "=.%BS%!substring!" <nul
> nul 2>&1 ping 127.0.0.1 -n 1
)
echo.
pause
GOTO :EOF
REM Subroutine to return the length of a string variable
:StrLen [string] [len-var]
set "_str=A%~1" & 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 %~2=%_len%
exit /b

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.

Batch macro displaying date and time followed by text

What I have done so far (displays both date and time on a WIN2K3 5.2.3790 machine with a leading space) :
SET DATETIME=(FOR /F %%C IN ('TIME/T') DO SET /P NOW=%%C : )&(FOR /F "TOKENS=2 DELIMS= " %%A IN ('DATE/T') DO SET /P NOW=%NOW% %%A <NUL)
%DATETIME%
I want to remove the leading space before the date that the set /p adds and add parameter for text but can't find a solution. I would also like to add a parameter for text as described here http://ss64.com/nt/syntax-macros.html once the set /p gets solved.
What I would like to get as a result (but with a batch macro instead of a call) :
#ECHO OFF
CALL :DATETIME "HELLO WORLD "
PAUSE>NUL
:DATETIME
FOR /F "TOKENS=*" %%A IN ('DATE/T') DO FOR %%B IN (%%A) DO SET NOW=%%B
FOR /F %%C IN ('TIME/T') DO SET /P NOW=%NOW% %%C %~1< NUL
Thank you,
I get the impression that the task is to echo a date and time and text on the same line:
echo %date% # %time% - "Hello World"
As you referenced the macros at ss64.com you should try to use the syntax shown there.
It's not necessary but a good way to use the %\n% formatting.
#ECHO OFF
set LF=^
::Above 2 blank lines are required - do not remove
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
SET DATETIME=( %\n%
FOR /F "TOKENS=*" %%A IN ('DATE/T') DO ( %\n%
FOR /F %%C IN ('TIME/T') DO SET /P "NOW=%%A%%C "^<NUL%\n%
)%\n%
)
set datet
echo ------
%DATETIME%
echo Hello World

Resources