If file exists get its contents with batch script - windows

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.

Related

How to set a variable with an environment variable read from a text file

I've created the following config file which contains parameters to be used by a batch file:
File winscp.conf:
folder %appData%\winscp
version 5.7.4
visit http://sourceforge.net/projects/winscp/files/WinSCP/
download http://sourceforge.net/projects/winscp/files/WinSCP/5.7.4/winscp574.zip
Batch file (get.bat):
#echo off
setlocal
#if not exist "%1" (
echo Config file not found in "%1"
exit /B
)
#for /f "tokens=1,2 delims= " %%A in (%1) do (
set %%A=%%B
)
mkdir %folder%
When I call the batch file like this:
get.bat winscp.conf
I get a sub-folder %appData%\winscp created in the current folder, something like this:
c:\Temp\%appData%\winscp
While what I want is a winscp folder created in the Windows app data folder, something like this:
C:\Users\Caffe\AppData\Roaming\winscp
I think there's something wrong with the statement set %%A=%%B, since if I change it to set %%A=%appData%\winscp I do get the folder created the way I want.
I just summarize the answers of wOxxOm and JosefZ with adding some small improvements.
#echo off
setlocal EnableExtensions
set "ConfigFile=%~1"
if "%ConfigFile%" == "" (
echo %~nx0 must be called with name of configuration file
echo as first parameter, for example: %~nx0 winscp.conf
goto EndBatch
)
if not exist "%ConfigFile%" (
echo Config file "%ConfigFile%" not found.
goto EndBatch
)
set "folder="
for /F "usebackq tokens=1*" %%A in ("%ConfigFile%") do call set "%%A=%%B"
if "%folder%" == "" (
echo Option "folder" not defined in config file "%ConfigFile%".
goto EndBatch
)
mkdir "%folder%" 2>nul
:EndBatch
endlocal
For better reading what first argument passed to the batch file should be, the parameter is immediately assigned to an environment variable without the surrounding quotes which must be used if configuration file name with or without path contains anywhere at least 1 space character.
Next a check is made if batch file was called at all with a parameter.
After FOR loop it is verified if the configuration file really contained an entry for folder.
And creation of directory is made with using quotes because folder path can contain spaces, and with redirecting any error message to device nul, i.e. suppress the error message output if directory exists already.
The variables inside tokens should be expanded prior to the assignment by adding call:
call set %%A=%%B
With next changes in your code:
call set instead of set
for /f "tokens=1,* instead of for /f "tokens=1,2
then next code snippet should work:
#ECHO OFF
SETLOCAL enableextensions
if not exist "%1" (
echo Config file not found in "%1"
exit /B
)
for /f "tokens=1,* delims= " %%A in (%1) do (
call set "%%A=%%B"
)
mkdir %folder%

Not looping through all the files

Windows batch script:
I have three files in a drectory.I`m trying to loop through the multiple files located in the directory and rename the files,but some how its not looping through.
i can see that the var1 is getting the right file name but not for sub1.This in turn renames the other two files in the directory with wrong output. Could some one please help me on this.
#echo on & setlocal EnableDelayedExpansion
set a=9
for /f "tokens=*" %%i in ('dir /b "C:\XX\YY\ZZ*"') do (
set var1=%%i
SET sub1=%var1:~7,22%
ECHO %sub1%
ren "%%i" "ABC!sub1!_!a!.dat"
set /a a+=1
)
#echo on
setlocal EnableDelayedExpansion
set a=10001
for /f "tokens=*" %%i in ('dir /b "C:\TEST\PBM\PAR*"') do (
set var1=%%i
SET sub1=!var1:~7,22!
ECHO !sub1!
ECHO ren "%%i" "ABC!sub1!_!a!.dat"
set /a a+=1
)
With delayedexpansion any reference to the value of a variable that is changed within the loop must use the !var! syntax. %var% will access the parse-time value.
Note: REN is now echoed for verification.

How do I write a batch that is copying itself?

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!
)

Store Multiline String in Batch Variable

I need to remove a string that may occur inside a file. The string has many lines. Can I perform this action using a Batch script?
I've heard that you cant have variables with more than one line in Batch? The string will come from another file that I will read into a variable using Batch.
The following code seems to only store the 1st/last line of a file in the string?? Whats going wrong?
Rem Read file and store all contents in string
Set replace=
Set target=
Set OUTFILE=res.txt
for /f "delims=" %%i in (myFile.txt) do set target=%target% %%i
echo %target%
Rem When I print target I only have one line not many lines?? Whats going wrong
Rem Remove the target string from myOtherFile.txt: this code is from http://stackoverflow.com/questions/5273937/how-to-replace-substrings-in-windows-batch-file
for /f "tokens=1,* delims=ΒΆ" %%A in ( '"type myOtherFile.txt"') do (
SET string=%%A
SET modified=!string:%target%=%replace%!
echo !modified! >> %OUTFILE%
)
Try this:
#echo off &setlocal enabledelayedexpansion
for /f "delims=" %%i in (myFile.txt) do set "target=!target! %%i"
echo %target%
Inside a code block you need always delayed expansion for variables with variable values.
Try this, change last to:
echo !target!

Set ECHO / TYPE output as a Variable in Batch Files

Is it possible to set the output of TYPE or ECHO as a variable in a batch file?
Convoluted, and it only works for a single line, but general:
for /f "delims=" %%x in ('some command with output') do set "Var=%%x"
For echo you don't need to do anything special, just change
echo Foo
into
set Var=Foo
And for files there is also the option of either
set /p Var=<file.txt
or
for /f "delims=" %%x in (file.txt) do set "Var=%%x"

Resources