Find and Replace not working for batch file - file

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.

Related

Batch File - How to copy text from file, and then update it to a new value

Each time I open the batch file, I would like it to read the information currently stored in the text file, and then apply that stored information it pulled to calculating a new integer.
I'm trying to figure out how to get a number copied from a text file, stored as a variable, and then updated to a new integer in that text file, say adding 1 to the value.
I've been sifting through information online, and everything seems to point in a different direction.
Here is a test code I've gotten from digging thus-far:
set file="Test.txt"
set /a _Counter =< %file%
echo:%_Counter%
set /a "_Update=%_Counter%+1"
echo:%_Update% >%file%
timeout /t 10
For some reason when I try to get the information for the counter, it doesn't pull any data from the text file, and I'm left with this line output by the batch file.
F:\Users\Test\Documents\JumbledDirectory> set /a _Counter = Directory\Test.txt 0<F:\Users\Test\Documents\Jumbled
The most common answer I've seen is to use something along the lines of
set /p _Counter=< Test.txt
echo %_Counter%
As seen here: Windows batch command(s) to read first line from text file
But upon doing this I've either ended up with
echo:%_Counter%
being completely blank, or it defaults to 0 each time.
Any help would be appreciated as I've sadly been trying to find how to get this simple function for around 6 hours now.
#ECHO Off
SETLOCAL
set "file=q72474185.txt"
set /p _Counter=< "%file%"
echo:%_Counter%
set /a _Update=_Counter+1
echo:%_Update% >"%file%"
TYPE "%file%"
GOTO :EOF
When you use the point-click-and-giggle method of executing a batch, the batch window will close if a syntax-error is found or the script runs to completion. You can put a pause after statements and home in on the error, but better to open a 'command prompt' and run your batch from there so that the window remains open and any (error) messages will be displayed.
The error message would be about missing operand.
I've changed the filename as I track each question I respond to with its own set of data.
Use set "var=value" for setting string values - this avoids problems caused by trailing spaces. Don't assign a terminal \, Space or " - build pathnames from the elements - counterintuitively, it is likely to make the process easier.
set /a does not expect input from anywhere, it simply performs the calculation and assigns the result. Quotes are not necessary so I've removed them. % are also not required in a set /a but can be required if you are using delayedexpansion.
set /p expects input, so I've used that to read the file. Note that set /a disregards spaces, but set and set /p will include the space before the = in the variablename assigned, and _Counter & _Counter are different variables.
So having the batch in the same directory as the textfile this will work:
REM get input of file as Counter
set /p Counter=<number.txt
REM add a number to Counter and assign it as Counter
set /a "Counter=%Counter%+3
REM empty the file
break>number.txt
REM write Counter in the file
echo %Counter% >> number.txt

How to extract text and set as variable Batch Code CMD

I would like to extract what users are online based on this text file:
https://minecraft-statistic.net/en/server/167.114.43.185_25565/json/
I will save it as a text file. Inside that there is something:
"players_list":["Raskhol"]["Lukaka"],"map":...etc
I would like to extract all the text between "_list": and ,"map" and set it as a variable. So that when I call the variable %Playerlist%, it would say:
["Raskhol"]["Lukaka"]
similar to #geisterfurz007's answer, this one assumes the you are after the first instance of "players_list": before the first instance of ,"map"
#Echo Off
Set/P var=<some.json
Set var=%var:,"map"=&:%
Set var=%var:*"players_list":=%
Echo=%var%
Timeout -1
Not tested due to beeing on phone.
#echo off
For /f "delims=: tokens=2" %%g in (PathTo\file.txt) do (
Set var=%%g
Goto:next
)
:next
Set var=%var:,map=%
echo %var%
Assumes players are the first to be listed.
Reads the file, takes the part after the first : up to the second one, stores it in var.
Then ,map gets replaces with nothing to result in just the players beeing echoed in the end.
Feel free to ask questions if something is unclear! Might take a while as I am currently mobile though.

Conditional IF function for Batch File

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.

How would I set each line of a text document to separate variables using batch?

How would I set a each line of a text document to separate variables using Batch? I know how to set a variable to the first line of a text document using:
Set /p Variable=<Test.txt
...but I don't know how to read other lines of the file. Lets say for example I had a text document with 3 lines, the first line had 'Apples' written on it, the second had 'Bananas' and the third had 'Pears', and lets say the document was called Fruit.txt. How would I set the variable 'Line_1' to the first line of the document, 'Line_2' to the second line and 'Line_3' to the last line?. Just to keep it simple, lets just say the batch file and Fruit.txt are both in the same folder. I don't want to do this in VBScript, so please only post Batch code. I would have thought that it would be something like:
#Echo off
Set /p Line_1=<Fruit.txt:1
Set /p Line_2=<Fruit.txt:2
Set /p Line_3=<Fruit.txt:3
Echo Fruit 1 is %Line_1%, Fruit 2 is %Line_2% and Fruit 3 is %Line_3%
Pause
Exit
...but quite clearly it isn't. Any help?
EDIT: This is for arbitrary-length files, then. jeb has an answer that solves your particular problem for a known number of lines. I will leave this here, though, as I hate deleting posts I put some time into for explanation :-)
Well, you obviously need some sort of counter. Let's start with 1:
set Counter=1
Then, you need to go line-wise through the file:
for /f %%x in (somefile) do ...
Then store the line in a numbered variable (that's what we have the counter for):
set "Line_!Counter!=%%x"
aaaaand increment the counter:
set /a Counter+=1
And that's it. Add a few more necessary things, you know, the boring stuff that's always needed in such cases (strange statements before and after, block delimiters, etc.), and you're done:
#echo off
setlocal enabledelayedexpansion
set Counter=1
for /f %%x in (somefile) do (
set "Line_!Counter!=%%x"
set /a Counter+=1
)
set /a NumLines=Counter - 1
Echo Fruit 1 is %Line_1%, Fruit 2 is %Line_2% and Fruit 3 is %Line_3%
rem or, for arbitrary file lengths:
for /l %%x in (1,1,%NumLines%) do echo Fruit %%x is !Line_%%x!
Some explanation:
set /p Var=<file will set the variable to the first line of a file, as you noted. That works because set /p will prompt for input and < file will redirect the file into standard input of a command. Thus set /p will interpret the file's contents as the entered input up until the user hits Return (i.e. the file contains a line break). That's why you get the first line. The system would throw the whole file at set /p but since the command only reads the first line and then is done they just get discarded.
The syntax you were proposing there is actually for accessing Alternate Data Streams of files on NTFS, which is somethhing totally different.
<short-detour> However, jeb has a way of reading multiple lines. This works because the block (delimited by parentheses) is a single command (see below) you can redirect a file's contents into. Except that command is comprised of multiple statements, each of which will read a single line and store it away. </short-detour>
Which brings us to for /f which iterates over the contents of a file (or the output of a command) line by line and executes a command or block of commands for each line. We can now read the whole file into as many variables as there are lines. We don't even need to know how many in advance.
You may have noticed the Line_!Counter! in there which uses Counter a little bit differently from how you're used to use environment variables, I guess. This is called delayed expansion and is necessary in some cases due to how cmd parses and executes batch files. Environment variables in a command are expanded to their values upon parsing that command. In this case the whole for /f including the block containing two statements is a single command for cmd. So if we used %Counter% it would be replaced by the value Counter had before the loop (1) and never change while the loop is running (as it is parsed once and run multiple times. Delayed expansion (signaled by using ! instead of % for variable access changes that and expands environment variables just prior to running a command.
This is almost always necessary if you change a variable within a loop and use it within the same loop again. Also this makes it necessary to first enable delayed expansion which is done with the setlocal command and an appropriate argument:
setlocal enabledelayedexpansion
set /a will perform arithmetic. We use it here to increment Counter by one for each line read.
To read multiple lines with set/p you need brackets around the set/p block.
#Echo off
(
Set /p Line_1=
Set /p Line_2=
Set /p Line_3=
) <Fruit.txt
Echo Fruit 1 is %Line_1%, Fruit 2 is %Line_2% and Fruit 3 is %Line_3%

storing returned values from functions present in exe file using bat script

I am trying to call a function present in saur.exe using bat.
It looks something like this:
saur.exe readName
When i execute it, it returns a string "Saurabh".
Now that I want to store "saurabh" in a variable called name.
So I am doing :
set name = saur.exe readName
echo .%name%
In this case, it doesnot execute.
It gives blank in front of echo command.
For some strange reason, doing what you want requires some awkward workarounds. The long way would be to store the output of the command in a file, then read the file into the variable, and finally delete the file. The shorter (and barely readable) way is:
for /f "delims=" %%a in ('saur.exe readName') do set name=%%a
echo %name%
:-(
Some SET command documentation will show that you can only assign strings to environment variables (http://www.computerhope.com/sethlp.htm).
In your example above, you have actually set an environment variable called:
"name "
Yet you are echoing the variable:
"name"
The best solution I can find is to do something similar to
saur.exe readName>tempFile
SET /p variableName=<tempFile
ECHO %variableName%
Hopefully this helps :)

Resources