I have written a batch file that runs fine under Windows Command Prompt, but I would like to be able to run it after POST in DOS. I have copied my code to AUTOEXEC.BAT file which gets executed automatically; however it comes up with syntax errors once it reaches the call command and the rest.
echo. This script is counting the # of POSTs.
echo. The POST # value is saved in TEST.txt.
echo.
call:myPOSTTest
for /f "tokens=* delims=" %%x in (A:\TEST.txt) do echo POST# %%x
echo. &pause&goto:eof
::--------------------------------------------------------
::-- Function section starts below here
::--------------------------------------------------------
:myPOSTTest - here starts my function identified by its label
set var=0
if EXIST A:\TEST.txt (
for /f %%x in (A:\TEST.txt) do (set /a var=%%x+1)
)
echo %var% >> A:\TEST.txt
goto END
:END
Thank You
See below for comments:
echo. This script is counting the # of POSTs.
echo. The POST # value is saved in TEST.txt.
echo.
call:myPOSTTest
MSDOS doesn't support the call :label syntax
for /f "tokens=* delims=" %%x in (A:\TEST.txt) do echo POST# %%x
MSDOS doesn't support the extended for commands
echo. &pause&goto:eof
MSDOS doesn't support the & command separator or the goto :eof link
::--------------------------------------------------------
::-- Function section starts below here
::--------------------------------------------------------
:myPOSTTest - here starts my function identified by its label
set var=0
if EXIST A:\TEST.txt (
for /f %%x in (A:\TEST.txt) do (set /a var=%%x+1)
)
MSDOS doesn't support the compound expressions in parentheses or the set /a enhancement
echo %var% >> A:\TEST.txt
goto END
:END
A little bit late, but ...
The call :function syntax can be substituted by an additional file for each function or by trampoline code on the batch file entry.
#echo off
for %%P in (/%1.) do if %%P==: goto %1
echo Program started
call %0 :func1
call %0 :func2 With :args
goto :eof
:func1
echo This is func1 with args: %1, %2, %3
goto :eof
:func2
echo This is func2 with args: %1, %2, %3
goto :eof
:eof
For the arithmetic part in set /a var=%%x+1 you can use an inc.bat or add.bat.
Even reading and processing lines from a text file is possible with old DOS.
Related
I am basic user of the Windows command prompt and I am getting automatically shut down of this console when parsing the variable defa to the called function. I used %defa% and !defa! not working, although echo shows that the for structure is changing the variable in the right direction. I leave below my code in case that somebody can help me to correct it:
#echo off
setlocal enabledelayedexpansion
cd C:\Users\LAPTOPJOSE\Desktop\IMAGEMAGICK\images
set/a "th=870"
for /f "delims=" %%m in ('dir /b /o:n') do if not defined defa set "defa=%%m"
REM Loop calling Callme and updating "defa"
FOR %%h in (*.png) DO (
echo Defa parsed !defa!
call:Callme %defa% "%%h" %th%
set "defa=%%h"
echo DefaUpdated !defa!
)
:Callme
echo Parameters %1 %2 %3
pause
magick compare -metric RMSE %1 %2 NULL: 2>C:\Users\LAPTOPJOSE\Desktop\IMAGEMAGICK\outputresult.txt
for /F "tokens=2* delims= " %%C in (C:\Users\LAPTOPJOSE\Desktop\IMAGEMAGICK\outputresult.txt) do set "var2=%%~C"
echo Var2 %var2%
set /A res=%var2:~4,3%
echo Result %res%
::Line that causes the console shut down without completing the action
IF %res% GTR %3 (copy %2 C:\Users\LAPTOPJOSE\Desktop\IMAGEMAGICK\diff-images)
GOTO:EOF
I'm making a game and I want a personalized username option that only appears once.
Here is an example:
#echo off
:onetime
echo please enter a username
echo.
set /p newuser=%newuser%:
echo %newuser%> cfg.txt
goto menu
:menu
for /f "tokens=* delims=" %%x in (cfg.txt) do echo %%x
cls
...
I'm trying to figure out how to make :onetime happen once, so that it sends the username to cfg.txt
Anyone know how?
I have cleaned up your code and provided a completed working script, and noted where you will put your game code.
Although Delayed expansion is not needed for this code, I have placed it in the script as you had it in your original script.
Please be mindful of the variable names I have chosen as they are used in several locations.
I have tried to comment the code with info on what it is doing, and I would be happen to explain further if needed.
I'd like to actually play your game when you are completed with it, if I may. :)
Hope that helps.
Ben
BPG.cmd
REM Script: BPG.cmd
REM Version: 1.0
REM Description: Game to play about Monsters.
Rem Notes: Currently Implementing Menu System.
Rem Sets up Variables and checks if the script needs to be re-called.
#(
SETLOCAL ENABLEDelayedExpansion
echo off
SET "eLvl=0"
SET "ScriptFolder=%~dp0"
SET "Log=%~dpn0.log"
SET "ConfigFile=%~dpn0_cfg.txt"
IF /I "%~1" NEQ "MAX" (
ENDLOCAL
ECHO.Game not started Maximized, Opening in a New Window by Running: Start "BPG 1 A Batch of Monsters" /MAX "%~dpnx0" MAX
Start "BPG 1 A Batch of Monsters" /MAX "%~dpnx0" MAX
EXIT /b %eLvl%
)
COLOR 2
)
REM Calls Main Function.
CALL :Main
REM Ends the script.
(
ENDLOCAL
EXIT /b %eLvl%
)
REM Main Function, most of your coding goes here, and this function calls sub functions.
:Main
Rem Check if Config file exists, if it does not, then call the New User Function.
IF NOT EXIST "%ConfigFile%" (
CALL :NewUser
)
Rem Load Username from Config file.
FOR /F "Tokens=*" %%A IN ('Type "%ConfigFile%"') DO (
SET "_UserName=%%~A"
)
Rem Call Menu System
CALL :Menu
REM Based off the option chosen Either Start a new Game or Skip to the End.
REM ECHO.CALL %_Menu_Choice%
CALL %_Menu_Choice%
GOTO :EOF
:NewUser
SETLOCAL
REM Get the Username Input
SET /P "_User=Please Enter a Username: "
REM Output the Username to the config file, overwriting all the file contents:
echo.%_User%>"%ConfigFile%"
ENDLOCAL
GOTO :EOF
:Menu
SETLOCAL
REM Output the Config file contents:
Type "%ConfigFile%"
REM Clear the screen
cls
echo ______ _______ _______
echo I ___ \ I ____ I I ____ \
echo I I I II I II I I \/
echo I I__/ / I I____II I I
echo I __ I I _____I I I ____
echo I I \ \ I I I I \_ I
echo I I___I II I I I___I I
echo I______/ I_/ I_______I A BATCH OF MONSTERS
echo.
echo.
echo 1) Begin
echo.
echo 2) Exit
echo.
set /p "_Choice=%_UserName%, Enter a Number: "
(
REM End the local variable Space, and Set return variables based on the choice, or re-draw the menu.
ENDLOCAL
IF /I "%_Choice%" EQU "1" (
REM ECHO.%_Choice% EQU 1
SET "_Menu_Choice=:Begin_Game"
) ELSE (
IF /I "%_Choice%" EQU "2" (
REM ECHO.%_Choice% EQU 2
SET "_Menu_Choice=GOTO :EOF"
) ELSE (
ECHO.%_Choice% Not Valid!
PAUSE
GOTO :Menu
)
)
)
goto :EOF
:Begin_Game
REM All the remaining code for your game should probably go here.
GOTO :EOF
try checking file existence :
#echo off
:onetime
setlocal enableDelayedExpansion
if not exist "cfg.txt" (
echo please enter a username
echo.
set /p newuser=%newuser%:
echo !newuser!> cfg.txt
goto menu
)
:menu
for /f "tokens=* delims=" %%x in (cfg.txt) do echo %%x
cls
I write a batch file to get the start time of cmd in for statement:
for /L %%i in (1,1,3) do (
echo %%i
echo "traceroute %%i start at %date% %time%" >tr%%i.txt
adb shell "/data/local/traceroute smtp.163.com" 2>&1 >>tr%%i.txt
)
but got the same time in 3 result file:
"traceroute 1 start at 2013/03/27 周三 15:48:47.12"
"traceroute 2 start at 2013/03/27 周三 15:48:47.12"
"traceroute 3 start at 2013/03/27 周三 15:48:47.12"
What's wrong?
A FOR loop is parsed from the FOR to its final closing parenthesis (ie. ALL of the codesegment you posted. At this time, ANY %var% will be replaced by the THEN-CURRENT (ie. PARSE-TIME) value of the variable. THEN the code is executed.
Hence %date% %time% were replaced by their values at the time the command was PARSED.
You can overcome the problem in at least three ways:
1/ with DELAYED EXPANSION, invoked by a SETLOCAL ENABLEDELAYEDEXPANSION instruction, when %var% STILL shows the PARSE-TIME value, but !var! shows the RUN-TIME value
2/ Indirect expansion by CALLing %%var%%
3/ Use a subroutine or external batchfile
Try this code:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%i IN (1 2 3) DO (
ECHO START of run %%i
ECHO using ^!time^! : !time! - PARSE TIME was %time%
CALL ECHO using CALL %%%%TIME%%%% : %%TIME%%
CALL :report
timeout /t 5
ECHO using ^!time^! : !time!
CALL ECHO using CALL %%%%TIME%%%% : %%TIME%%
CALL :report
ECHO END of run %%i
ECHO.
)
GOTO :eof
:report
ECHO :report says TIME is %TIME%
GOTO :eof
You should use delayed expansion !variable!s:
#echo off &setlocal enabledelayedexpansion
for /L %%i in (1,1,3) do (
echo %%i
echo "traceroute %%i start at !date! !time!" >tr%%i.txt
adb shell "/data/local/traceroute smtp.163.com" 2>&1 >>tr%%i.txt
)
A while ago I made a function that you can call from the command prompt or any batch file (it was just for fun, I don't see how it could be useful). It basically just makes your (Microsoft) computer speak whatever you wrote in as the parameter.
I recently got some inspiration to add a switch to it where it would read the contents of a file. My standalone script worked, but when I added it to my function, it didn't work as I would have liked.
Here's the code:
#echo off & setlocal enabledelayedexpansion
if "%~1"=="/?" (
echo.
echo TALK "Text" [Parameters]
echo.
echo Text - The phrase you want to be spoken.
echo.
echo [Parameters]:
echo /f - Read the contents of a file. "Text" changes to the file path.
echo.
endlocal
exit /b
)
if "%~2 X" equ "/f X" (
if not exist %~1 (
echo File does not exist or cannot be found.
endlocal
exit /b
)
set cont=
for /f "delims=" %%i in (%~1) do set cont=!cont! %%i
:b
echo Set a = Wscript.CreateObject("SAPI.SpVoice") > "Talk.vbs"
echo a.speak "%cont%" >> "Talk.vbs"
start /WAIT Talk.vbs
del Talk.vbs
endlocal
exit /b
)
set text=%~1
echo set speech = Wscript.CreateObject("SAPI.spVoice") > "talk.vbs"
echo speech.speak "%text%" >> "talk.vbs"
start /WAIT talk.vbs
del Talk.vbs
endlocal
exit /b
Unfortunately I don't have working function code (before I added the /f switch).
This is a last resort for me as I've edited it heavily and scoured the code for any give away as to what the problem might be.
Another bad thing is that I didn't take note of what I changed, so I can't exactly tell you what I've tried. I can tell you what the outputs are though.
The first time I tried, it gave the output The syntax of the command is incorrect.
It's now at the point where the original function (just converting text to speech) doesn't work anymore. The contents of the file Talk.vbs (which was made during the process) is a.speak "".
I'll keep updating my attempts, but knowing me it's something really simple that I've overlooked.
--EDIT--
At the suggestion of someone, I put carats before the square brackets in the syntax section. Nothing changed.
Along with escaping the parenthesis you also had to surround if exist %~1 in quotes in case of a argument of "some words I want it to say". Also cleaned it up a bit. Code at the bottom, but first an explanation.
If you looked at talk.vbs before it was deleted you would see this:
a.speak "!cont! contents of the file here"
This is because of this code:
for /f "delims=" %%i in (%~1) do set cont=!cont! %%i
:b
echo Set a = Wscript.CreateObject("SAPI.SpVoice") > "Talk.vbs"
If you turned echo on and watched the code you would see the last unescaped ) was taking the contents of the for loop and including it in the redirect.
Corrected and cleaned code:
#echo off & setlocal enabledelayedexpansion
if "%~1"=="/?" (
echo.
echo TALK "Text" [Parameters]
echo.
echo Text - The phrase you want to be spoken.
echo.
echo [Parameters]:
echo /f - Read the contents of a file. "Text" changes to the file path.
echo.
endlocal
exit /b
)
set text=
if [%2]==[/f] (
if exist "%~1" (
for /f "usebackq delims=" %%i in (%1) do set text=!text! %%i
) else (
endlocal
exit /B
)
)
if [%2]==[] set text=%~1
echo set speech = Wscript.CreateObject^("SAPI.spVoice"^) > "talk.vbs"
echo speech.speak "%text%" >> "talk.vbs"
cscript //NoLogo //B talk.vbs
del Talk.vbs
endlocal
exit /b
Edit: fixed the for statement pointed out by Andriy M
In your echo statements that contain parentheses, try escaping the parentheses with carats. I suspect especially the echo within the if statement is partially getting evaluated literally.
One other minor suggestion, I would also replace
start /WAIT Talk.vbs
with
cscript /nologo Talk.vbs
It's not that I think the start /wait is causing the error, but it does cause a second console window to appear temporarily for no good reason -- or it will whenever your script executes that far, anyway.
I made a few other suggested changes here, such as eliminating the need for a /f switch. If "%1" is the name of a file that exists, read it. Otherwise, treat it as text to read. And instead of having a separate subroutine for reading a file versus getting text from input, all that needs to happen is a variable has a different value.
#echo off & setlocal enabledelayedexpansion
if "%1"=="/?" ( goto usage )
if "%1"=="" ( goto usage )
if "%1"=="--help" ( goto usage )
if exist "%1" (
set txt=
for /f "usebackq tokens=*" %%i in (%1) do set txt=!txt! %%i
) else (
set txt=%1
)
echo Set a = Wscript.CreateObject^("SAPI.SpVoice"^) > "talk.vbs"
echo a.speak "%txt%" >> "talk.vbs"
cscript /nologo talk.vbs
del talk.vbs
endlocal
goto :EOF
:usage
echo.
echo TALK ["text"^|filename]
echo.
echo talk filename -- speaks the contents of filename
echo talk "text" -- speaks the supplied text
endlocal
goto :EOF
I'm looking for a DOS batch program that takes a file:
First input line
Second input line
Third input line...
And outputs "First input line"
you can just get the first line like this
set /p firstline=<file
echo %firstline%
Assuming you mean the Windows cmd interpreter (I'd be surprised if you really were still using DOS), the following script will do what you want:
#echo off
setlocal enableextensions enabledelayedexpansion
set first=1
for /f "delims=" %%i in (infile.txt) do (
if !first!==1 echo %%i
set first=0
)
endlocal
With an input file of infile.txt as:
line 1
line 2
line 3
this will output:
line 1
This will still process all the lines, it just won't print those beyond line 1. If you want to actually stop processing, use something like:
#echo off
setlocal enableextensions enabledelayedexpansion
for /f "delims=" %%i in (infile.txt) do (
echo %%i
goto :endfor
)
:endfor
endlocal
Or you could just go get your hands on Cygwin or GnuWin32 and use the head program. That's what I'd do. But, if that's not an option (some workplaces don't allow it), you can create a similar cmd file in Windows itself as follows (winhead.cmd):
#echo off
setlocal enableextensions enabledelayedexpansion
if x%1x==xx goto :usage
if x%2x==xx goto :usage
set /a "linenum = 0"
for /f "usebackq delims=" %%i in (%1) do (
if !linenum! geq %2 goto :break1
echo %%i
set /a "linenum = linenum + 1"
)
:break1
endlocal
goto :finish
:usage
echo.winhead ^<file^> ^<numlines^>
echo. ^<file^>
echo. is the file to process
echo. (surround with double quotes if it contains spaces).
echo. ^<numlines^>
echo. is the number of lines to print from file start.
goto :finish
:finish
endlocal
why not use the more +1 command via a pipe?
e.g.
type something | more +1