Firstly this is a work around to another issue, but to not complicate this question I'll not go into what the original approach was.
Now I am trying to use a batch file to:
Read a text log file,
loop through to the penultimate line of the file
then do a conditional check to see if the last entry was a confirmation that a process had completed successfully or another message which would indicate it did not.
Based on the result of step 3 above, return the value of 0 for pass and 1 for fail so that SSIS can interpret the result.
The name of the text file is fed into the batch file as a parameter.
Everything seems to work except for when I try to include an IF statement at which point it just doesn't return any result.
Can anybody advise what I'm doing wrong? - have tried to follow the guidance here: http://ss64.com/nt/if.html but clearly without success!
#ECHO off
setlocal EnableDelayedExpansion
for /f "delims=" %%x in (%1) do (
set "previous=!last!"
set "last=%%x"
)
IF !last! == "EXPORT completed successfully" ECHO 1 ELSE ECHO 0
If the last line is changed to say ECHO !last! it correctly returns the string EXPORT completed successfully. I have tried the above code with & without quotes but to no success.
Any help would be appreciated as I've never had to use batch before.
Thanks
You were very close! Note that I've added brackets around your IF and ELSE clauses. I've also added quotes around your last.
Finally, bear in mind that the whitespace around an IF...ELSE in batch is actually important - see this answer for details.
#ECHO off
setlocal EnableDelayedExpansion
for /f "delims=" %%x in (%1) do (
set "previous=!last!"
set "last=%%x"
)
IF "!last!" == "EXPORT completed successfully" (
ECHO 1
) ELSE (
ECHO 0
)
ECHO !last!
I think that when you set a value in a command line using the set command, you should refer to this variable using %. For example:
#echo off
cls
:loop
rem DO SOMETHING
set /p userinp=Repeat (y,n)?
if "%userinp%" == "y" (goto loop)
pause
This batch does something and then asks a user if the procedure needs to be repeated using a userinp variable. Hope this helps.
Related
I'm trying to create a batch file to insert a string from a .txt file at a specific place inside a string in 225 batch files - i.e., inserted into one line in the file at a specific place - but this question concerns the inserting part, and not the loop part, so I've left out the latter in my code example. It's also currently just displaying the text on-screen; not actually writing it to files.
The target files are a bunch of launch .bat files used for running a game server cluster using a tool, so I will have to leave each of them with the same names as they start with (Start XXYY.bat). They contain something along these lines:
start /high ShooterGame\Binaries\Win64\ShooterGameServer.exe Ocean?ServerX=0?ServerY=0?AltSaveDirectoryName=0000?ServerAdminPassword=1234?MaxPlayers=50?ReservedPlayerSlots=25?QueryPort=50002?Port=5002?SeamlessIP=192.168.1.225?RCONEnabled=true?RCONPort=28450 -log -server -NoBattlEye
exit
Where the ServerX, ServerY, AltSaveDirectoryNamen and all three Port settings are unique to each server, so these will have to remain unchanged.
I need to add several more settings, from another .txt file in the final version, but for this example I will just put the additions (the word INSERT added after the ReservedPlayerSlots setting, while keeping each setting divided by question marks) directly into this script.
My code is actually doing exactly what I want it to, but unfortunately it doesn't stop at that point, and decides to append more text than I wanted; specifically, everything I add to the ECHO command which is not a variable name.
To clarify, I get the exact output that I want... Plus the unwanted addition of a bunch of question marks and the word INSERT, which apparently come from my ECHO command, but I just have no idea why they get re-added.
My knowledge of batch scripting is fairly limited, so there might well be something basic that I've overlooked.
I've tried replacing the question marks in the output (which are required to be questions marks in the final version) with normal letters instead, but it doesn't change the behaviour; they were still appended to the expected output, just like the question marks they replaced.
#ECHO OFF
SET FileNum=0000
REM I will have the code loop through 225 files (0000-1414) in the final version, but for test purposes I just set it to one single file number manually here.
SET FileName=Start %FileNum%.bat
REN "%FileName%" temp.txt
FOR /F "tokens=1,2,3,4,5,6,7,8,9,10,11,12 delims=?" %%a IN (temp.txt) DO (
ECHO %%a?%%b?%%c?%%d?%%e?%%f?%%g?INSERT?%%h?%%i?%%j?%%k?%%l
)
REN temp.txt "%FileName%"
I expect this code to output this:
start /high ShooterGame\Binaries\Win64\ShooterGameServer.exe Ocean?ServerX=0?ServerY=0?AltSaveDirectoryName=0000?ServerAdminPassword=1234?MaxPlayers=50?ReservedPlayerSlots=25?INSERT?QueryPort=50002?Port=5002?SeamlessIP=192.168.1.225?RCONEnabled=true?RCONPort=28450 -log -server -NoBattlEye
exit
But what I am getting is this:
start /high ShooterGame\Binaries\Win64\ShooterGameServer.exe Ocean?ServerX=0?ServerY=0?AltSaveDirectoryName=0000?ServerAdminPassword=1234?MaxPlayers=50?ReservedPlayerSlots=25?INSERT?QueryPort=50002?Port=5002?SeamlessIP=192.168.1.225?RCONEnabled=true?RCONPort=28450 -log -server -NoBattlEye
exit???????INSERT?????
Which is the expected output, but with the unexpected re-addition of every symbol in the ECHO command which did not designate a variable at the end of the output (in this case ???????INSERT?????), just after the exit.
I'm stumped... I hope someone has an idea what I'm doing wrong here.
Okay, I applied the idea that aschipfl provided, and it seems to work now.
The IF NOT "%%b"=="" line seems to have done the trick, after I added the final line with the exit using another ECHO. My full script (including loop and write to file) is now like this:
#ECHO OFF
SETLOCAL EnableDelayedExpansion
SET "Insert=SettingOne=True?SettingTwo=False?SettingThree=1.000000"
FOR /l %%x IN (0, 1, 14) DO (
FOR /l %%y IN (0, 1, 14) DO (
IF %%x LSS 10 (SET XNum=0%%x) ELSE (SET XNum=%%x)
IF %%y LSS 10 (SET YNum=0%%y) ELSE (SET Ynum=%%y)
SET "FileNum=!XNum!!YNum!"
SET "FileName=Start !FileNum!.bat"
ECHO Filename: !FileName!
REN "!FileName!" temp.txt
(
FOR /F "tokens=1-12 delims=?" %%a IN (temp.txt) DO (
IF NOT "%%b"=="" (
ECHO %%a?%%b?%%c?%%d?%%e?%%f?%%g?%Insert%?%%h?%%i?%%j?%%k?%%l
ECHO exit
)
)
) >edited.txt
REN edited.txt "!FileName!"
DEL /q temp.txt
ECHO has been updated
)
)
This is now working exactly as intended.
It's quite possible that there is a more elegant way of doing this, and I am cartain that there is a way of making this more general and less hard-coded, but it's good enough for my purposes.
I thank you for your help!
I have been writing some batch files now-a-days. I am beginner !. So i have made a custom batch in which by entering a setup name it launches it but. I'am having some problem creating this custom file.
#echo off
set /p lnk="Setup Name = "
if "%lnk%"=="install.itunes.x64.windows" goto itunes
:itunes
start=(path)(setup.exe).....
cls
But if a user enters "itues or "installitunes" or "KJEWBFciou" whatever that don't matchs my custom command I want a error Pop-up in this condition.
What can i Do?
and don't ask to put "if not "%lnk%" i have already tried help level:0
Because i have many setups like itunes if input will not equal to custom command it launches the next setup.
Please help me
Please igonre my errors i only made 'em here not in batch file.
in line 2 %lnk% , lnk
and line 3 "%lnk" ,"%lnk%"
Ok so..
1 #echo off
2 set /p %lnk%="Setup Name = "
3 if "%lnk%=="install.itunes.x64.windows" goto itunes
4 :itunes
5 start=(path)(setup.exe).....
6 cls
A few errors but you're close.
In line 2, you use:
set /p %lnk%=="Setup Name = " goto itunes
When setting a variable you can't use %% around it, but thats only used when comparing, because when creating the variable, the computer will replace [set /p %lnk%=] with [set /p =] which is invalid syntax.
In line 3:
if "%lnk%=="install.itunes.x64.windows" goto itunes
You never closed the quotes on the left of the '==' comparison. Do note you can also use [if %val1% equ %val2%] to the same results, which can help when you want to use other comparison tags.
A sidenote for the task you have set, although [goto itunes] works fine, its a good habit to use [goto :itunes] instead, and if you want to keep your code all together, you can just make a code block like:
if %val1% equ %val2% (
rem do stuff here
)
do note, if you either want a task to run if variables match, and if not try the next match, you can use multiple of these. Otherwise you can use:
if %val1% equ %val2% (
rem do stuff here
) else (
rem do other stuff here
)
In response to your issue on it launching the next command, thats because in line 3, you check if the variable matches your string, but if it doesnt batch skips it and runs the next line, which is your :itunes label.
All in all, this should work better, after you fix [start=(path)(setup.exe).....] to launch as desired.
#echo off && color f0 && title Itunes
:top
cls
set /p lnk="Setup Name = "
if "%lnk%"=="install.itunes.x64.windows" (
start=(path)(setup.exe).....
cls
)
cls
echo "%lnk%" was not matched to any choices...
pause
goto :top
:: _Arescet
I'm really new in this forum so I hope to respect all your rules, if not please forgive me!
I've just started studying something about batch files and I'm trying to execute a simple program from batch passing a parameter (the last aim is to submit a SAS program passing a date parameter).
Is it possible to activate a sort of list where I can choose some between pre-defined parameters?
--> This is the real aim of my work
I'm trying to "play" with this code:
#echo off
title Setting up execution period
echo Insert your date in the format GGMMMAAAA (es: '31DEC2003'D).
SET /p data_par=Insert the date to filter datas:
SET first_byte=%data_par:~1,1%
if "%first_byte%"=="" (
GOTO tag1
) else (
GOTO tag2
)
:tag1
msg * Missing value
:tag2
msg * Well done!
pause
I've tried in a lot of ways but it looks like the IF statement is not executed, I don't know where am I wrong.
Another question: why the prompt closes after i press "Enter" (afte the set/p command is executed)?
--> this has been resolved putting the "pause" command at the end of the script.
Thank you all for the attention,
Best regards!
Squotty
Put a pause at the end of your code to see the errormessages.
correct syntax for if when using else is:
if "a"=="b" (dosomething) else (dosemethingelse)
You can write it in several lines, but there are rules, where to set the paratheses:
if "a"=="b" (
echo this is code for something
rem more lines possible
) else (
echo this is code for something else
rem more lines possible
)
The first ( has to be on the same line than if.
) else ( have to be on one line.
If you press just enter with set /p, the variable remains unchanged (propably empty), so your code will go on with the code and hits the line else. Here it will tell you "else is not recognized as a command..."
at your tagx you should tell batch, where to stop execution. Use goto :eof to stop execution or goto somewhere to continue somewhere else. If you don't, it will just continue with the next lines.
Example:
:tag1
msg * Missing value
goto :eof
:tag2
msg * Well done!
goto :continue
pause
:continue
REM go on with the program...
(note: the pause will never be reached. I let it there to show you, how things work)
EDIT instead of just checking for some input you can check for the correct format:
echo %data_par%|findstr /r "[0-3][0-9][A-Z][A-Z][A-Z][1-2]0[0-9][0-9]">nul && (
echo correct format
goto continue
) || (
echo wrong format
goto startover
)
It's not bullet proof (eg. 38ABC2019 would be considered "correct"), but at least it checks for the correct format (e.g. 15.12.2019 or 12/15/2014 would be "not correct")
#ECHO OFF
SETLOCAL
SET "item1=date1"
SET "item2=date2"
SET "item3=date3"
SET "item4=date4"
FOR /l %%a IN (1,1,4) DO CALL ECHO(%%a. %%item%%a%%
ECHO(U. User-specified
choice /c 1234u
CALL SET selection=%%item%errorlevel%%%
IF NOT DEFINED selection (
SET /p selection="Your date-selection ? "
)
IF NOT DEFINED selection ECHO No selection made&GOTO :EOF
ECHO selection is %selection%
GOTO :EOF
This code may be of assistance.
It's normal to develop batch code using a batch window. Simply set up a shortcut to command prompt (Start>Programs>Accessories) which would allow you to run the script over and over and retain the results on-screen without using 'pause'. Editing can be accomplished by using notepad batchfilename.bat from the prompt (if you are using notepad for an editor - if using something better, then substitute that program's name). You can exit from the batch window by executing an exit command.
You can also get help on batch commands by using commandname /? - it's often cryptic and there are plenty of quirks. Extensive help available here on SO.
It's a simple bat script that should checkout some folders from svn . I'm not that up on bat scripting, there seems to be no consistency on how variables are referenced.
For instance the variable "branchV" does not get appended it is seen as '""', but if I echo it I see the user input.
set "DB_DIRECTORIES=AuditUser-db CarrierProcessingRules-db iDetectDB-db iRisk-db WarningsIndex-db"
set "SVNBASEURL=http://XX.XX.XX.XX:7777/svn/YYY"
set BASELOCALDIRECTORY="C:"
#echo on
#cls
#echo Check out DB directories from?
#echo
#echo 1. Trunk
#echo 2. Branch
#echo
#echo
#set OPTIONSELECTED=
#set /P OPTIONSELECTED=SELECT OPTION:%=%
if "%OPTIONSELECTED%" == "1" (
set SVNURL="%SVNBASEURL%/trunk"
set BRANCHV="BCSTrunk"
) ELSE IF %OPTIONSELECTED% == 2 (
#echo
#echo
#echo
#echo PLEASE ENTER THE BRANCH VERSION YOU WISH TO CHECKOUT
#echo
#echo
#set branchV=
#set /P branchV=ENTER VERSION:%=%
#echo
set SVNURL="%SVNBASEURL%"/branches/"%branchV%"
) ELSE (
#echo Invalid option
)
for %%i in (%DB_DIRECTORIES%) do (
set PATHTOUSE="%BASELOCALDIRECTORY%"/"%branchV%"/%%i
set NEWSVNURL="%SVNURL%"/%%i
REM Intended to remove all inverted commas , which were causing an issue in svn
set PATHTOUSE="%PATHTOUSE:=%"
set NEWSVNURL=%NEWSVNURL:=%
TortoiseProc.exe /command:checkout /path:%PATHTOUSE% /url:%NEWSVNURL% /closeonend:1
)
In batch scripts, when a line or a block of code (the code enclosed in parenthesis) is reached, all variable reads are replaced with the value they have before starting to execute that line or block. So, if you change a variable inside a block, you can not retrieve this value inside the same block. There are no reads of the variable value, they were replaced with its values.
To correctly retrieve the changed value inside the same block, it is necessary to indicate to cmd that the read operations should be delayed until the line is executed. To do this, two steps are necessary. First is enable this option
setlocal enabledelayedexpansion
When it is enabled, variables that should be read delayed need the sintax !var! instead of %var%
Ok so I am creating a script with a built in updater, it creates a new file with the following code and updates several variables, but for some reason this isn't working anyone have any idea how to fix it or a similar script that will do roughly the same thing.
#echo off
setlocal enabledelayedexpansion
set /p "findthis"="1"
set /p "replacewith"="1.2.3"
call:updater
set /p "findthis"="2"
set /p "replacewith"="2.3.4"
call:updater
set /p "findthis"="3"
set /p "replacewith"="3.4.5"
call:updater
goto:eof
:updater
for /f "tokens=*" %%a in (updateme.bat) do (
set write=%%a
if %%a==%findthis% set write=%replacewith%
echo !write!
echo !write! >>%~n1.replaced%~x1
)
goto:eof
there are several errors in this BAT.
Some are obvious syntax errors.
Read help set and correct all the set /p "this"="value" (hint: don't use /p option and correct the usage of " in the variable name)
you try to use %1 in a CALLed label. This is a passed parameter, and you are not passing it in your CALL. Read HELP CALL.
Some are logic errors.
The :updater code appends the updated string to the output file. It does so three times, so the final code is three times the original code with the strings changed.
Also, the code does try to find the string as a full line, a line containing just "1" in a BAT file does not make too much sense to me. You would probably want to find any text occurrence of "1".
Also, when you fix the previous problems, and if I understand correctly the intention of the code, you will eventually replace all "1" to "1.2.3" and then you replace all "2" to "2.3.4", so the original "1" will get replaced by "1.2.3.4.3".. and later on again, so it will finally be "1.2.3.4.5.4.3.4.5". Be careful with that.