How do I write a batch that is copying itself? - windows

I'd like to write a batch file, which reads its own code inside a string, then creates a new batch file with the string as content and execute it.

You can read the content of the started batch file with
type "%~f0"
Therefore, try something like
echo off
type "%~f0" > Test\file.bat
Test\file.bat
However, this script would repeat itself continously (or aborts if the directory Test does not exist). So you need to think about this approach (i.e. using conditional statements).

#echo off
setlocal DisableDelayedExpansion
if not exist newBatchFile.bat (
echo First execution!
set "batchFile="
for /F "usebackq delims=" %%a in ("%~F0") do (
set "line=%%a"
setlocal EnableDelayedExpansion
if "!line:~0,1!" equ ")" set "batchFile=!batchFile:~0,-1!"
set "batchFile=!batchFile!!line!"
if "!line:~-1!" neq "(" set "batchFile=!batchFile!&"
for /F "delims=" %%b in ("!batchFile!") do endlocal & set "batchFile=%%b"
)
setlocal EnableDelayedExpansion
echo !batchFile:~0,-1! > newBatchFile.bat
newBatchFile.bat
) else (
echo Second execution!
)

Related

If file exists get its contents with batch script

I want to access the contents of a JSON file via batch script to do some processing on it. my script is like this:
#ECHO OFF
SETLOCAL EnableDelayedExpansion
#setlocal enableextensions
#cd /d "%~dp0"
...
...
...
set FILEPATH=C:\\PROGRA~1\\Setup\\setup.json
IF EXIST "%FILEPATH%" (
set string=
for /f "delims=" %%x in (C:\\PROGRA~1\\Setup\\setup.json) do set "string=!string!%%x"
echo !string!
//do some processing on string variable
)
...
...
this script should return file contents but it prints all the environment variables & variables set in this script.
echo !string! returns ECHO is off(means string is empty).
if I run this code outside if() then it gives correct results(i.e file contents).
set string=
for /f "delims=" %%x in (C:\\PROGRA~1\\Setup\\setup.json) do set "string=!string!%%x"
echo !string!
So what am I missing here?
I couldn't find what was the underlying issue with using "file read with for loop inside if-exist block" but I found a workaround using "goto" statement.
set FILEPATH=C:\\PROGRA~1\\Setup\\setup.json
IF EXIST "%FILEPATH%" (goto getJson)
:getJson
set string=
for /f "usebackq delims=" %%x in ("C:\Program Files\Setup\setup.json") do set "string=!string!%%x"
echo !string!
this code gives the expected output.

Reading line by line from one file and write to another file using batch script

In below code i am tring to fetch the line no of string "AXX0000XXXA" from file data.txt,then fetching line by line and printing target.txt file,in between if the line reach the find line no i am adding one more line from file temp.txt.The code is working fine with the less nos of records(tested with 150 lines-File Size 100 kb),but when i am processing with 50K records(File Size 25MB) it is taking more then 25 minutes to process.could you please help me how i will process same in less time.
#echo off
setlocal enabledelayedexpansion
for /f "delims=:" %%a in ('findstr /n "AXX0000XXXA" "C:\Users\23456\Desktop\data.txt"') do (set find_line=%%a)
set /a counter=0
for /f "usebackq delims=" %%b in (`"findstr /n ^^ C:\Users\23456\Desktop\data.txt"`) do (
set curr_line=%%b
set /a counter=!counter!+1
if !counter! equ !find_line! (
type temp.txt >> target.txt
)
call :print_line curr_line
)
endlocal
:print_line
setlocal enabledelayedexpansion
set line=!%1!
set line=!line:*:=!
echo !line!>>target.txt
endlocal
Your code uses three Batch file constructs that are inherently slow: call command, >> append redirection and setlocal/endlocal, and these constructs are executed once per each file line! It would be faster to include the subroutine into the original code to avoid the call and setlocal commands, and an echo !line!>>target.txt command imply open the file, search for the end, append the data and close the file, so it is faster to use this construct: (for ...) > target.txt that just open the file once. An example of a code with such changes is in Compo's answer.
This is another method to solve this problem that may run faster when the search line is placed towards the beginning of the file:
#echo off
setlocal enabledelayedexpansion
for /f "delims=:" %%a in ('findstr /n "AXX0000XXXA" "C:\Users\23456\Desktop\data.txt"') do (set /A find_line=%%a-1)
call :processFile < "C:\Users\23456\Desktop\data.txt" > target.txt
goto :EOF
:processFile
rem Duplicate the first %find_line%-1 lines
for /L %%i in (1,1,%find_line%) do (
set /P "line="
echo !line!
)
rem Insert the additional line
type temp.txt
rem Copy the rest of lines
findstr ^^
exit /B
This should create target.txt with content matching data.txt except for an inserted line taken from tmp.txt immediately above the line matching the search string, AXX0000XXXA.
#Echo Off
Set "fSrc=C:\Users\23456\Desktop\data.txt"
Set "iSrc=temp.txt"
Set "sStr=AXX0000XXXA"
Set "fDst=target.txt"
Set "iStr="
Set/P "iStr="<"%iSrc%" 2>Nul
If Not Defined iStr Exit/B
Set "nStr="
For /F "Delims=:" %%A In ('FindStr/N "%sStr%" "%fSrc%" 2^>Nul') Do Set "nStr=%%A"
If Not Defined nStr Exit/B
( For /F "Tokens=1*Delims=:" %%A In ('FindStr/N "^" "%fSrc%"') Do (
If "%%A"=="%nStr%" Echo %iStr%
Echo %%B))>"%fDst%"
I have made it easy for you to change your variable data, you only need to alter lines 3-6.
I have assumed that this was your intention, your question was not clear, please accept my apologies if I have assumed incorrectly.

Replace a character to another one in a text file using Windows batch file

I'm trying to write a batch file that will replace every character . to / in my test.txt. However, something is wrong and my outfile.txt is generated empty.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=C:\Users\acaproni\Desktop"
SET "destdir=C:\Users\acaproni\Desktop"
SET "filename=%sourcedir%\test.txt"
SET "outfile=%destdir%\outfile.txt"
(
FOR /f "usebackqdelims=" %%a IN ("%filename%") DO (
SET "line=%%a"
SET "line=!line:.=/!"
ECHO !line!
)
)>"%outfile%"
GOTO :EOF
Anyone can help me?

Reading a file with for statment - Batch

I have this code:
#echo off
for /f "delims=" %%a in ("%~dp0\files\text\lead_r.txt") do set /p key= < lead_r.txt
ECHO %key%
PAUSE
What I want it to do is to open a specific text file, read it and then write what's in it to %key%. It works when lead_r.txt and the batch file are in the same folder but it fails when I move lead.txt to \files\text. There are no files with spaces in \files\text so i don't know where the problem is.
Thanks
Hard to understand your goal, but try next code snippet:
#echo off >Nul
setlocal EnableDelayedExpansion
for /f "delims=" %%a in ("%~dp0\files\text\lead_r.txt") do (
rem the same file in next line
rem set /p key=< lead_r.txt
set /p key= < %%a
ECHO !key!
PAUSE
)
endlocal
Here mind EnableDelayedExpansion keyword of setlocal command = Expand variables at execution time rather than at parse time, if used !key! syntax instead of %key% one.

remove all double quotes in a file.txt

What I have to do is a batch script that:
_read a file line by line
_remove all the double quote characters writing the result in a file
My attempt was a script like:
for /f "usebackq tokens=*" %%a in ("%GRUPPI3%.txt") do (
SET VARIAB=%%a
SET RESULT=%VARIAB:"=%
echo %RESULT% >> output.txt
)
After some try I realized that the PROBLEM IS THE VARIABLE "VARIAB"!
Doing an echo of VARIAB the result is null or an old value (like an old line read by the variable %%a). (Why "VARIAB" doesn't become a copy of "%%a" as I would expect?)
I can't understand such a behaviour...
Someone know the solution?
Thanks
Cristian
#ECHO OFF
SETLOCAL
(
for /f "usebackq tokens=*" %%a in ("%GRUPPI3%.txt") do (
SET "VARIAB=%%a"
IF DEFINED variab (
SETLOCAL enabledelayedexpansion
SET "RESULT=!VARIAB:"=!"
ECHO(!RESULT!
ENDLOCAL
)
)
)>newfile.txt
GOTO :EOF
This should fix your problem. I changed the detination file to suit my system. If you want to append to the destination file, use >> in place of >

Resources