Why am I getting "ECHO is OFF/ON"? - batch-file

Simple question: why is ECHO is OFF/ON being printed in a .txt file instead of the users' input? I tried various solutions - none of them worked. Any and all help will be appreciated.
Code
#echo off
:start
del "test.txt"
cls
set /p test_test = "> "
echo %test_test% >> test.txt
for /f "delims=" %%a in (test.txt) do (
set file = %%a
)
echo %file%
pause

The ECHO command with no parameters outputs the status of ECHO, which in this case you've set to off. Because your %test_test% variable is empty, (due to you setting a variable named %test_test %), the ECHO command is being entered with no parameters.
#echo off
:start
cls
set /p "test_test= > "
(echo %test_test%)>test.txt
for /f "delims=" %%a in (test.txt) do (
set "file=%%a"
)
echo %file%
pause
As you may have noted you werre also setting a variable named %file % too.

Related

Error Writing to file in .bat file

I have a .bat file that would ask your name and save it in a .txt file. If the file already exists, I want it to say "Your Name is ____"
#echo off
if exist BatchfileOutput.txt (
cls
FOR /F %%i IN (BatchfileOutput.txt) DO echo Your name is %%i
) else (
echo What is your name?
set /p %name%= )
echo %name% > BatchfileOutput.txt
pause
It prints ECHO is off, probably due to #echo off at the top. If I manually add text to the file, it displays the text. Could anyone help me get around this?
You need
set /p name=
not
set /p %name%=
which would set the variable named the current contents of NAME
It is set /P name= but not set /P %name%=.
The command echo %name% needs to be moved into the else block too. For this to work, delayed expansion must be established:
#echo off
if exist "BatchfileOutput.txt" (
cls
for /F "usebackq tokens=*" %%i in ("BatchfileOutput.txt") do echo Your name is %%i
) else (
echo What is your name?
set /P name=
setlocal EnableDelayedExpansion
> "BatchfileOutput.txt" echo !name!
endlocal
)
pause
I moved the redirection part to the front in order to avoid a trailing SPACE to be output also.
To avoid delayed expansion, you could avoid the parenthesised else block by using goto :Label as the last command of the if block, then omitting else and the parentheses, and then placing :Label before pause:
#echo off
if exist "BatchfileOutput.txt" (
cls
for /F "usebackq tokens=*" %%i in ("BatchfileOutput.txt") do echo Your name is %%i
goto :Label
)
echo What is your name?
set /P name=
> "BatchfileOutput.txt" echo %name%
:Label
pause
I quoted all file paths and therefore used the usebackq option of for /F in order to avoid trouble with such strings containing white-spaces. Furthermore, I stated the tokens=* option for the for /F loop to read the full line even in case the name consists of multiple words.

display a variable like %%i in for statements in variable? batch

How do I use a variable like %%i in a permanent variable?
(I don't really know the correct terms, so I hope anyone can figure out what I mean)
This is the code I am using:
#echo off
color 0f
goto number
:number
title number
cls
echo number of options?
set /p num=
goto option
:option
for /l %%i in (1,1,%num%) do (
cls
echo Name nr. %%i
echo Enter a option
set /p n%%i=
echo %%i = %n%%i% >> log.txt
)
goto select
:select
cls
echo %n2%
pause >nul
the "%n2%" works for whatever you put in second, but when I try to print it into a file ( echo %%i = %n%%i% >> log.txt ) it doesn't work.
I know the "%n%%i%" is not correct, But I don't really know what to actually put there.
:option
for /l %%i in (1,1,%num%) do (
cls
echo Name nr. %%i
echo Enter an option
set /p option%%i=
)
goto select
:select
set option>log.txt
cls
echo %option2%
You may like to consider this.
The command
set option
will show every environment variable that starts option in the format option1=Gido, which is why I changed n to option (there are other variables set that start n)

Batch file finding a filename which contains a substring

I want to write a batch file to find all .vsdm files and the file name must contain a substring "2.4". But my code is telling me that all my .vsdm files contains the substring "2.4" which is not correct.
FOR /R %completepath% %%G IN (*.vsdm) DO (
set file=%%~nG
If not "%file%"=="%file:2.4=%" (
echo Filename contains 2.4
) else (
echo Filename does NOT contains 2.4
)
)
Can anyone tell me where did I get it wrong?Thanks
If "%file%"=="%file:2.4=%" (
echo Filename "%file%" does NOT contain 2.4
) else (
echo Filename "%file%" contains 2.4
)
Including the filename in the echo may reveal more. I can see no reason for the double-negative approach. The way the code operates may depend on precisely where in code the instructions are located, for instance if these lines are contained within any variety of loop or code-block, operation may depend on other elements, so it's important to present the code in-context and with an example of what was expected and what actually happened.
correct fomatting makes all clear.
There are one or two SO articles about delayed expansion which OP should become familiar with.
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /R %completepath% %%G IN (*.vsdm) DO (
set "file=%%~nG"
If not "!file!"=="!file:2.4=!" (
echo Filename contains 2.4
) else (
echo Filename does NOT contains 2.4
)
)
ENDLOCAL
You can use the command Where /? that let you use wildcard characters ( ? * ) and UNC paths.
#echo off
Title Find the location of a file with substring by Hackoo
Color 0A
Call :inputbox "Enter the file name to search :" "Enter the file name to search"
If "%input%" == "" Color 0C & (
echo(
echo You must enter a filename to continue with this program
pause>nul & exit
) else (
Call :Browse4Folder "Select the source folder to scan %input%" "c:\scripts"
)
Set "ROOT=%Location%"
::We check whether the input string has an anti-Slach in the end or no ? if yes, we remove it !
IF %ROOT:~-1%==\ SET ROOT=%ROOT:~0,-1%
set whereCmd=where.exe /r %ROOT% %input%
for /f %%a in ('%whereCmd%') do echo %%~nxa --^> %%a
pause & exit
::***************************************************************************
:Browse4Folder
set Location=
set vbs="%temp%\_.vbs"
set cmd="%temp%\_.cmd"
for %%f in (%vbs% %cmd%) do if exist %%f del %%f
for %%g in ("vbs cmd") do if defined %%g set %%g=
(
echo set shell=WScript.CreateObject("Shell.Application"^)
echo set f=shell.BrowseForFolder(0,"%~1",0,"%~2"^)
echo if typename(f^)="Nothing" Then
echo wscript.echo "set Location=Dialog Cancelled"
echo WScript.Quit(1^)
echo end if
echo set fs=f.Items(^):set fi=fs.Item(^)
echo p=fi.Path:wscript.echo "set Location=" ^& p
)>%vbs%
cscript //nologo %vbs% > %cmd%
for /f "delims=" %%a in (%cmd%) do %%a
for %%f in (%vbs% %cmd%) do if exist %%f del /f /q %%f
for %%g in ("vbs cmd") do if defined %%g set %%g=
goto :eof
::***************************************************************************
:InputBox
set "input="
set "heading=%~2"
set "message=%~1"
echo wscript.echo inputbox(WScript.Arguments(0),WScript.Arguments(1)) >"%temp%\input.vbs"
for /f "tokens=* delims=" %%a in ('cscript //nologo "%temp%\input.vbs" "%message%" "%heading%"') do (
set "input=%%a"
)
exit /b
::***************************************************************************

Replace line in config file with batch afterward start exe

With a batch file, I want to change a value in a configuration file:
"title.connectionString" : "ServerIP",
ServerIP is the variable to be changed. So the batch file has to give people who use it an option to choose from 4 prefixed IPs. After they selected one of the 4 the IP, the config file has to be saved with new value and the batch file should run an executable.
Has anyone got an idea how I can do this with a batch file?
Easy, try this code:
#echo off
:start
Echo Select Ip:
Echo.
Echo 1. 10.0.0.0
Echo 2. 10.0.0.1
Echo 3. 10.0.0.2
Echo 4. 10.0.0.1
Echo.
Choice /c 1234 /m "Ip: " /n
set choice=%errorlevel%
set ip=
if %choice%==1 set ip=10.0.0.0
if %choice%==2 set ip=10.0.0.1
if %choice%==3 set ip=10.0.0.2
if %choice%==4 set ip=10.0.0.3
if "%ip%"=="" (Echo Error, null variable & goto :start)
ren config.txt config.tmp
setlocal Enabledelayedexpansion
for /f "tokens=*" %%a in (config.tmp) do (
set line=%%a
Echo !line:ServerIP=%ip%! >> config.txt
)
del config.tmp
And that should do what you want.
Mona
#echo off
setlocal enableextensions
call :replaceKeyValue "file.config" "title.connectionString" "123456789"
endlocal
exit /b
:replaceKeyValue file key value
setlocal enableextensions disabledelayedexpansion
ren "%~f1" "%~nx1.tmp" >nul && (
(for /f tokens^=1^,*^ delims^=^:^ eol^= %%k in ('findstr /n "^" ^<"%~f1.tmp"') do (
echo(%%l|findstr /c:"\"%~2\"" >nul && (
for /f "tokens=1 delims=:" %%v in ("%%l") do echo(%%~v : "%~3",
) || (
echo(%%l
)
)) > "%~f1"
del "%~f1.tmp" > nul
)
endlocal
This will handle the replacement of the value in the file. Monacraft answer shows a perfect way of selecting the required ip.
This will rename the file to file.tmp and for each line in the file (findstr /n is used to avoid lost of empty lines) it is tested agains the passed key. When required line is found, it is split using the colon (to keep the indentation) and value replaced with supplied value. All the non matching lines are echoed as is. All the output of the process is send to the original file and at end, the .tmp file is deleted.

Remotely check file size and get report

This script tries to:
get an input from a txt file, which is a list of computer names,
check if a log file on a computer from the list is bigger than 1000 bytes,
create a txt report with the names of those computers where the log file is more than 1000 bytes,
create another txt report with the names of the computers where the file is less than 1000 bytes.
However, something goes wrong. Any help could be nice.
#echo off
for /f "tokens=*" %%I in (computernames.txt)do call :checksz %%I
goto :eof
:checksz
setlocal
set file="\\%1\c$\data\info.log"
set min=1000
FOR /F "usebackq" %%A IN ('%file%') DO set size=%%~zA
if %size% GTQ %min% (
echo. %1 >>logsizemin.txt
) ELSE (
echo. %1>>logsizemax.txt
)
Hello everyone,
thanks for your valuable support. I congratulate whith those who conceived and built this site is really well done and useful.
I made some modifications to the script that you have kindly suggested to incorporate other features, but something is not working as I would like .. as you can view I use editv32 in order to hide password in my batch, the principle is the same but as you can see after checking the size of the log, "maxlongsize.txt" is used in order to take the names of the PCs on which do the next activity. I wish that the activities were performed sequentially on all PCs in the file "logsizemax.txt" with only one authentication at the beginning. I noticed that, for some reason sometimes the file "logsizemin.txt" is not created but i don't understand why. The maximum would be to put in another file such as "computer unreachable" those PCs that are not reached on the network but I have absolutely no idea how implement it. I hope I have sufficiently explained. Sorry for bad English! I think you understand my intention :). Following the batch
#setlocal
#echo off
editv32 -p "Enter username:" USR
editv32 -m -p "Enter password:" PWD
for /f "tokens=1" %%I in (computernames.txt) do call :checksz %%I
endlocal
goto :eof
:checksz
setlocal
set file="\\%1\c$\data\data.log"
set min=1000
type NUL>logsizemax.txt
type NUL>logsizemin.txt
if not exist %file% goto :eof
FOR /F "usebackq delims=" %%A IN ('%file%') DO set size=%%~zA
if %size% GEQ %min% ( echo %1>>logsizemax.txt ) ELSE ( echo %1>>logsizemin.txt )
endlocal
#setlocal
for /f "tokens=1" %%I in (logsizemax.txt) do call :sw %%I
endlocal
goto :eof
:sw
echo.
echo *****************************************
echo * VBS & Deploy script *
echo *****************************************
echo.
echo Run VBS and deploy script .....
psexec \\%1 -u %USR% -p %PWD% cscript "\\rep\Reg.vbs"
psexec \\%1 -u %USR% -p %PWD% cmd /c "\\rep\deploy.cmd"
echo.
echo **************************
echo * EXE Run *
echo **************************
echo.
echo Running exe .....
psexec -u %USR% -p %PWD% \\%1 "c:\Program Files\test.exe"
echo.
echo ***********************************
echo * Exe application launched *
echo ***********************************
echo.
goto END
:END
exit
You can avoid using environment variables and using the second FOR alltogether. Try this simpler version of your bat, with a more generic :checksz routine.
#echo off
for /f "tokens=*" %%a in (computernames.txt) do (
call :checksz "\\%%a\c$\data\info.log" 1000 "%%a"
)
goto :eof
:checksz
if %~z1 GTR %2 (
echo %~3 >> logsizemin.txt
) ELSE (
echo %~3 >> logsizemax.txt
)
goto :eof
see HELP CALL for more information.
Changes: GTG->GEQ, don't surround variable with quotes twice, remove leading space from echo, and a little clean up.
#setlocal
#echo off
for /f "tokens=1" %%I in (computernames.txt) do call :checksz %%I
endlocal
goto :eof
:checksz
setlocal
set file=\\%1\c$\data\info.log
set min=1000
if not exist %file% endlocal && goto :eof
FOR /F "usebackq delims=" %%A IN ('%file%') DO set size=%%~zA
if %size% GEQ %min% ( echo %1>>logsizemin.txt ) ELSE ( echo %1>>logsizemax.txt )
endlocal
goto :eof
edit: updated per comments from PA and Andriy M - endlocal if the file doesn't exist, and remove \ update note.

Resources