Batch file to edit .ini file but do not delete blank space - batch-file

I am new to StackOverflow. I want to run a batch file to find and replace a single string in an .ini file. I tried several solutions given on stackoverflow and other sites too.
A few of them are working - but delete my other lines having "space" or ";".
Here is the string that I want to find and change in my file RDConfigSettings.ini
CommunicationMode:1
I want it vice-versa:
if it is "CommunicationMode:1" then change it to "CommunicationMode:0"
if it is "CommunicationMode:0" then change it to "CommunicationMode:1"
Here is the whole content of my RDConfigSettings.ini file
;0 for Staging, 1 for Pre-Production, 2 for Production
RDEnviroment:2
;0 for disable, 1 for Enable
RDServiceLogs:0
;0 for disable, 1 for Enable
ClientValidation:0
;Validate Management Server Certificate -- 0 for Yes, 1 for No
ValidateCertificate:0
;Proxy Configuration -- 0 for Direct Internet Access, 1 for Access via Proxy
ProxyConfig:0
ProxyIP:[Proxy IP]
ProxyPort:[Proxy Port]
;0 for Https, 1 for Http
CommunicationMode:1
;Port Range Setting in below field
PortBegin:11100
PortEnd:11120
;ManagementServerURL
Registration:https://rdm.smartbioplus.com/rdm-device-app/registration
Keyrotation:https://rdm.smartbioplus.com/rdm-key-management-app/keyRotation
Telemetry:https://rdm.smartbioplus.com/rdm-telemetry-app/telemetry
Domain:rdm.smartbioplus.com
URL_Port:443
Could anyone help me? THis is my code:
#echo off
set "file=E:\CSC Softwares\MorphoRdServiceL0Soft\RDConfigSettings.ini"
:loop
findstr "^CommunicationMode:0$" "%file%" >nul || (
type "%file%"|repl "^CommunicationMode:1" "CommunicationMode:0" >"%file%.tmp"
move "%file%.tmp" "%file%" >nul
)
timeout 120 >nul
goto :loop
Moreover, it will be a great help if someone can add an Command with administrative rights that will stop a particular service "MORPHO_RD_Service" before replacing the string and then after replace the string, start the same service again.

You have code to switch from 1 to 0, but no code to switch from 0 to 1.
Below code alternates between 1 and 0 with each run of the loop.
I also changed to jrepl (more modern and powerful). It isn't necessary (though possible) to process piped data and redirect the result to another file. The /f switch gives the inputfile to process, the /o switch gives the outputfile. By giving it a single -, it uses the same filename as the input file (and overwrites it with the new(changed) data).
#echo off
set "file=t.txt"
:loop
findstr "^CommunicationMode:" "%file%" & REM this line for troubleshooting only
findstr "^CommunicationMode:0$" "%file%" >nul && (
call jrepl "CommunicationMode:0" "CommunicationMode:1" /f "%file%" /o -
) || (
call jrepl "CommunicationMode:1" "CommunicationMode:0" /f "%file%" /o -
)
timeout 1 >nul
goto :loop
Don't forget to adapt the data file name and the timeout to your needs.

Without the need for an external utility such as jrepl, which is great for some things, but not needed for such a task:
#echo off
setlocal enabledelayedexpansion
set "file=E:\CSC Softwares\MorphoRdServiceL0Soft\RDConfigSettings.ini"
for /f "tokens=1,*delims=]" %%i in ('type "%file%" ^| find /v /n "" ^& break^>"%file%"') do (
set "line=%%j"
if "!line!" == "CommunicationMode:1" (
set "line=!line:1=0!"
set "hold=!line!"
) else if "!line!" == "CommunicationMode:0" (
set "line=!line:0=1!"
set "hold=!line!"
)
echo(!line!>>"!file!"
)
echo Changed to !hold!
pause

Related

Batch File - Hosts file editor - prevent duplicate entries - delete previously added entries

Okay here is what I got so far.
This is meant to add websites to block in the hosts file, as well as allow the user to delete the entries when they want to. When trying to add a website to block sometimes it creates a new line then puts the entry on the line before it. This is not what I want. I want it to create a new line then add the entry on that line. For some reason it works sometimes and other times it don't work at all. I get an error message that says Find parameter is incorrect. I am using the Find command to see if the entries is already in the hosts file. If it is I want it to avoid adding it. If it is not then I want to add it. When I try to delete a entry the batch just crashes, so I am not really sure what I am doing wrong here. I am trying to find the entry and replace it with nothing. What I really want to do is delete the entire line so that I don't end up with a lot of blank lines.
Any help is greatly appreciated. Thanks!
#echo off
TITLE Modifying your HOSTS file
COLOR F0
:LOOP
cls
SET "CHOICE="
ECHO Choose 1 to block a website
ECHO Choose 2 remove a blocked website
ECHO Choose 3 to exit
SET /P CHOICE= selection %CHOICE%
GOTO %CHOICE%
:1
cls
SET /P WEBSITE=Enter the name of the website to add:
SET HOME= 127.0.0.1
SET NEWLINE=^& echo.
SET BLOCKEDSITE=%HOME% %WEBSITE%
FIND /C /I %BLOCKEDSITE% %WINDIR%\system32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 0 ECHO %NEWLINE%^%BLOCKEDSITE%>>%WINDIR%\System32\drivers\etc\hosts
ECHO Website blocked
ping 127.0.0.1 -n 5 > nul
GOTO LOOP
:2
cls
SET /P WEBSITE=Enter the name of the website to remove:
SETLOCAL ENABLEEXTENTIONS DISABLEDELAYEDEXPANSION
SET "HOME= 127.0.0.1 "
SET "BLOCKEDSITE=%HOME% %WEBSITE%"
SET "REPLACE="
SET "HOSTSFILE=%WINDIR%\system32\drivers\etc\hosts"
FOR /F "DELIMS=" %%i IN ('TYPE "%HOSTSFILE%" ^& BREAK ^> "%HOSTSFILE%" ')
DO
(
SET "LINE=%%i"
SETLOCAL ENABLEDELAYEDEXPANSION
>>"%HOSTSFILE%" echo(!LINE:%BLOCKEDSITE%=%REPLACE%!
ENDLOCAL
)
ECHO Website unblocked
GOTO LOOP
:3
EXIT
Please note that the term website is misleading when referring to the entries of the hosts file. The entries of hosts file are used for custom mappings of DNS host names to IP addresses, and any host name that is present in the file does not necessarily hosts a website. Using the term website may lead to the false impression that something like http://www.example.com can be added to hosts file which is not true.
Skipping a host if it is already present in the hosts file:
The problem with your usage of find is that %BLOCKEDSITE% has embedded spaces so you should enclose it quotes and use:
FIND /C /I "%BLOCKEDSITE%" %WINDIR%\system32\drivers\etc\hosts
But it has another problem: Because of its dependency on the exact spacing between the IP address and host name which is mandated by %BLOCKEDSITE% It only works for the entries that are added by your batch file. Additionally the user may have commented out (disabled) an entry by placing # in the begging of the line that contains the entry, and your batch code will skip adding the host even if the entry is disabled.
This can be resolved by using findstr with its regex syntax. for example:
findstr /IRC:"^ *127\.0\.0\.1 *example\.com *$" "%WINDIR%\system32\drivers\etc\hosts"
Removing an entry from the hosts file:
In the FOR loop you just have to skip writing the lines that contains the specified entry:
if "!Line!"=="!LINE:%BLOCKEDSITE%=!" echo(!Line!>>"%HOSTSFILE%"
But again it is not accurate and is suffering from the same problems that are mentioned earlier for skipping adding the entry. Again By using findstr you can easily remove the lines that contain the unwanted entry:
findstr /VIRC:"^ *127\.0\.0\.1 *example\.com *$" "%HOSTSFILE%" > "%HOSTSFILE%.tmp"
del "%HOSTSFILE%"
ren "%HOSTSFILE%.tmp" "hosts"
With above mentioned points the script can be rewritten like this:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
title Modifying your HOSTS file
color F0
set "HOSTSFILE=%WINDIR%\system32\drivers\etc\hosts"
set "HOME=127.0.0.1"
set "PROMPT_TEXT=Enter the host name to"
set "ACTION_TEXT[1]=add"
set "ACTION_TEXT[2]=remove"
set "FindEmptyLine=^ *$"
set "NewLineAppended="
cls
setlocal EnableDelayedExpansion
:LOOP
echo,
echo 1. Block a host
echo 2. Remove a blocked host
echo 3. Exit
choice /C "123" /N /M "Choose an item [1, 2, 3]: "
set "Item=%errorlevel%"
goto choice%Item%
:choice0 // User Pressed CTRL-C
:choice3
exit /b
:choice1
call :Common
set "HostEntry=!HOME! !HOST!"
findstr /IRC:"!FindEntry!" "!HOSTSFILE!"> nul && (
echo The host !HOST! is already blocked, No action taken.
) || (
if not defined NewLineAppended (
REM This will append a new line ONLY if the file does not end by LF character
type "!HOSTSFILE!" | findstr $ > "!HOSTSFILE!.tmp" && (
del "!HOSTSFILE!"
ren "!HOSTSFILE!.tmp" "hosts"
set "NewLineAppended=1"
)
)
echo !HostEntry!>>"!HOSTSFILE!"
echo The host !HOST! blocked
)
goto LOOP
:choice2
call :Common
findstr /VIR /C:"!FindEntry!" /C:"!FindEmptyLine!" "!HOSTSFILE!">"!HOSTSFILE!.tmp" && (
del "!HOSTSFILE!"
ren "!HOSTSFILE!.tmp" "hosts"
echo The host !HOST! unblocked
)
goto LOOP
:Common
set "HOST="
set /P "HOST=!PROMPT_TEXT! !ACTION_TEXT[%Item%]! (e.g. example.com): "
if not defined HOST (
(goto)2>nul
goto LOOP
)
set "FindEntry=^^ *!HOME! *!HOST! *$"
set "FindEntry=!FindEntry:.=\.!"
exit /b

Batch unzip files in child folders, then copy specific files to network folder based on number in file name

I am a serious newbie at creating batch files and am hoping someone can help me. One of our staff receives zipped pdf docs by email, which she copies to a folder on her desktop. Within that folder, I would like for her to run a batch script that will
A. Unzip the zipped contents into a network directory, i.e. \server\contracts
Under this directory, the process will create folders for each group of contracts, i.e. \server\contracts\Masterson (The name of this will be same as zipped file name).
B. Then the batch process should copy a select few of the pdf documents into a network directory based on the filename. Each file contains a number, which will go in the following manner: Masterson + 1.pdf >> \server\contracts\Item1 and \server\contracts\Item2, etc. Masterson + 1.pdf will go into \server\contracts\Item1 without a folder name, as will Paisley + 1 certificate.pdf and Johnsonville + 1 document.pdf.
The problem is that the companies do not follow instructions and the number can be at the beginning, middle, or end of the file name. Also, unfortunately, there are spaces in the name of the zipped file and the pdf documents. Currently, we are only copying 4 filenames into separate directories for other people to review and validate.
Below is what I did so far looking around this site:
#Echo off
SETLOCAL
for /R "delims=\\server\contracts\RECEIVED 2017-18 APPLICATION" %%I in
("*.zip") do (
"%ProgramFiles(x86)%\7-Zip\7z.exe" x -y -o"%%~dpnI" "%%~fI"
)
rem setlocal enableextensions disabledelayedexpansion
CLS
::The Input Folder
set "InputFolder=C:\Users\eartha.kitt\Desktop\Test"
::The Output Folders
set "Output1=\\server\contracts\ITEM 1 17-18 CERTS"
set "Output6=\\server\contracts\ITEM 6 SIGNATURES"
set "Output8A=\\server\contracts\ITEM 8A 17-18 CALENDARS"
set "Output8B=\\server\contracts\ITEM 8B 16-17 REVISED CALENDARS"
set "Output8a=\\server\contracts\ITEM 8A 17-18 CALENDARS"
set "Output8b=\\server\contracts\ITEM 8B 16-17 REVISED CALENDARS"
::The extensions to wait
set "extensions=*.pdf"
setlocal EnableDelayedExpansion
:Loop
cls
echo Waiting for file ...
for /f "usebackq delims=|" %%a in ('dir /b /s %InputFolder%\%extensions%
2^>nul') do (
rem for /r %%a in in (%InputFolder%\%extensions% 2^>nul') do (
set "Fichier=%%a"
echo Treating _^> %%a
if "!Fichier:~0,-2!"==" 1" COPY "%%~a" %Output1%
if "!Fichier:~0,-2!"==" 6" COPY "%InputFolder%\~%%a" %Output6%
if "!Fichier:~0,-3!"=="8A" COPY "%InputFolder%\%%a" %Output8A%
if "!Fichier:~0,-3!"=="8B" COPY "%InputFolder%\%%a" %Output8B%
if "!Fichier:~0,-3!"=="8a" COPY "%InputFolder%\%%a" %Output8a%
if "!Fichier:~0,-3!"=="8b" COPY "%InputFolder%\%%a" %Output8b%
::Waiting ~5 seconds
ping localhost -n 6 >nul
)
::Return to the loop
goto:Loop
Of course this doesn't work. Please help!
Well - bravo for the attempt! And so close...
Let's take the first part
for /R "delims=\\server\contracts\RECEIVED 2017-18 APPLICATION" %%I in ("*.zip") do (
"%ProgramFiles(x86)%\7-Zip\7z.exe" x -y -o"%%~dpnI" "%%~fI"
)
What's wrong here is that the delims clause is only usable in for /f. for /r always delivers the entire filename to the metavariable %%I.
On my system I use %server%\u for testing - u is a shared resource on the server assigned to U:\ on server.
for /R "\\%server%\u\contracts\RECEIVED 2017-18 APPLICATION" %%I IN ("*.zip") do (
"%ProgramFiles(x86)%\7-Zip\7z.exe" x -y -o"%%~dpnI" "%%~fI"
worked happily for me - delivering the extracted files to "u:\contracts\RECEIVED 2017-18 APPLICATION"
The second part of your code is examining "C:\Users\eartha.kitt\Desktop\Test" not "\%server%\u\contracts\RECEIVED 2017-18 APPLICATION" - very sensibly assigned to a variablename for easy adjustment.
Here's my modified code:
SET "terminatefilename=stop.txt"
DEL "%terminatefilename%" 2>nul
rem setlocal enableextensions disabledelayedexpansion
CLS
::The Input Folder
set "InputFolder=C:\Users\eartha.kitt\Desktop\Test"
set "InputFolder=\\%server%\u\contracts\RECEIVED 2017-18 APPLICATION"
::The Output Folders
set "Output1=\\%server%\u\contracts\ITEM 1 17-18 CERTS"
set "Output6=\\%server%\u\contracts\ITEM 6 SIGNATURES"
set "Output8A=\\%server%\u\contracts\ITEM 8A 17-18 CALENDARS"
set "Output8B=\\%server%\u\contracts\ITEM 8B 16-17 REVISED CALENDARS"
FOR /f "tokens=1*delims==" %%b IN ('set output') DO MD "%%c" 2>nul
::The extensions to wait
set "extensions=*.pdf"
setlocal EnableDelayedExpansion
:Loop
cls
echo Waiting for file ...
for /f "delims=|" %%a in ('dir /b /s "%InputFolder%\%extensions%" 2^>nul') do (
rem for /r %%a in in (%InputFolder%\%extensions% 2^>nul') do (
SET "copied="
echo Treating _^> %%a
REM OPTION 1 - Key string must be at end-of name part
set "Fichier=%%~Na"
if /i "!Fichier:~0,-2!"==" 1" COPY "%%a" "%Output1%"&SET "copied=Y"
if /i "!Fichier:~0,-2!"==" 6" COPY "%%a" "%Output6%"&SET "copied=Y"
if /i "!Fichier:~0,-3!"==" 8A" COPY "%%a" "%Output8A%"&SET "copied=Y"
if /i "!Fichier:~0,-3!"==" 8B" COPY "%%a" "%Output8B%"&SET "copied=Y"
REM OPTION 2 - Key string may be anywhere in filename
IF NOT DEFINED copied (
echo "%%~na"|FINDSTR /i /L /C:" 8B" >NUL
IF NOT ERRORLEVEL 1 COPY "%%a" "%Output8B%"&SET "copied=Y"
)
IF NOT DEFINED copied (
echo "%%~na"|FINDSTR /i /L /C:" 8A" >NUL
IF NOT ERRORLEVEL 1 COPY "%%a" "%Output8A%"&SET "copied=Y"
)
IF NOT DEFINED copied (
echo "%%~na"|FINDSTR /i /L /C:" 6" >NUL
IF NOT ERRORLEVEL 1 COPY "%%a" "%Output6%"&SET "copied=Y"
)
IF NOT DEFINED copied (
echo "%%~na"|FINDSTR /i /L /C:" 1" >NUL
IF NOT ERRORLEVEL 1 COPY "%%a" "%Output1%"&SET "copied=Y"
)
)
::Waiting ~5 seconds
timeout 6 >NUL
:: Test for exit
IF EXIST "%terminatefilename%" DEL "%terminatefilename%"&GOTO :EOF
::Return to the loop
goto:Loop
First, I set up terminatefilename so that creating this file will terminate the batch (it's an infinite loop by design in your code)
Next, I overrode your inputfolder name to suit my system.
Then the output directories. I adjusted their names to suit my system. Note that batch is largely case-insensitive, so setting Output8A and Output8a is setting the same variable. The only time that batch commands are case-sensitive is the metavariable (loop-control variable) in a for statement.
Then I inserted a line to create the destination directories. This uses a set command to list the variables starting output in the format Output1=\\%server%\u\contracts\ITEM 1 17-18 CERTS (where server will have been resolved). The command reads the output of the set command, uses = as the delimiter and assigns output1 to %%b and \\%server%\u\contracts\ITEM 1 17-18 CERTS to %%c. We want to make sure the directory %%c exists, so we make it with an md command and ignore complaints that it already exists with 2>nul.
Next the for/f. for /f reads each line of (thisfilename) or ("this literal value") or ('the output of this command') but when you need to read a from a file whose name must be double-quoted beacuse it contains spaces, then the syntax is for /f "usebackq"... (idontknow) or ("this filename containing spaces") or ('ive no idea whatever') or (`the output of this command`)
So there's no need to use usebackq -- in fact, it's counterproductive.
The delims=| is optional and could be replaced by delims= as the output of a dir command will never contain | (illegal in a file or directoryname). You do need the delims clause however, as the default delimiters include Space and the default tokens is 1 so only the first string of each line output up to the first space will be assigned to %%a.
Hmm - you've remmed-out a for/r. Sadly, the target directory in the for /r can't be a metavariable.
Next, I've cleared a copied flag saying "so far, this file has not been copied"
Next, set fichier to the name-part only of the filename. Since you are using .pdf as a filter, each name output by the for/f will be a full-filename, ending in .pdf
Next, almost-correct with the battery of if statements. The /i makes the comparison case-insensitive so that it will cope with both 8a and 8A. The strings on both sides of the == must be identical to pass the == test, so you need a 3-character string in the 8 tests.
You've evidently been experimenting with the copy command and trying to feed it with appropriate strings. %%~a strips %%a of any enclosing quotes. %%a won't have enclosing quotes - just the fullfilename, so this does nothing in this instance. %InputFolder%\~%%a concatenates the values from InputFolder,"\~" and %%a - which means "%inputfolder%\~%inputfolder%\filenameandextension of %%a". The last two would be resolved to the same, bar the ~.
Since the entire filename is contained in %%a, all that's needed for the sourcefile is "%%a" - quoted as it will probably contain spaces.
Well - the destination directory (we've already established it with the for /f...%%b) can also contain spaces, so it needs to be quoted, too.
I've then set the flag copied to Y if the line took effect. Actually, it can be set to any non-empty value as the whole object is to interpret whether or not it exists with an if defined statement to bypass any later attempts to copy the same file (remember - copied is cleared for each file)
Now - the second option. This is actually a more powerful detector of the required target strings than is the substring version, and will detect the target string anywhere in the filename.
If you echo the name-part only of the file %%~na into a findstr, then set to findstr to look for the /L literal string /i case-insensitive c:"some literal string" and output ny matches found to nowhere (>nul) then findstr will set errorlevel to 0 if found and 1 otherwise. (the /L is superfluous here, I use it habitually to remind me I'm working with literal strings, not regular expressions)
If errorlevel n will be true if errorlevel is currently n or greater than n, so if the string is found, we do the copy and set the copied flag as before.
I reversed the order of tests because it was easier for me to do using the editor I use.
Now - there's a downside to this approach. It's a double-edged sword. Since the target string is detected wherever it appears in the filename, whatever whatever 10 something something.pdf will pass the test for 1 because Space1 appears in its name.
When the loop has finished, use timeout to wait, redirecting the output to nul to make it pipe down. Note that your delay was inside the for loop - so it would have waited 6 seconds after processing each file, not 6 seconds after processing an entire batch.
Finally, if you create terminatefilename from anothe cmd instance, the batch will exit cleanly and kill terminatefilename for you. Much cleaner than control-c.
A last note: Since you are copying the file, not MOVEing it, it will still exist in the same place presumably after the 6 seconds has elapsed and will be endlessly copied and recopied. You'd probably need to make adjustments to achieve the desired result.

Batch Renaming Files-

I am trying to make a program that will gather some documents and data, rename them, encrypt them and store them on a removable disk. While I have found a way to gather the documents, and encrypt them, I have yet to determine how to rename all the documents. Preferably the name of the documents would be a randomly generated string.
My current code is as followed:
#echo off
color a
ipconfig > D:\DONOTDELETE\DONOTDELETE\ip.txt
net user > D:\DONOTDELETE\DONOTDELETE\users.txt
tasklist > D:\DONOTDELETE\DONOTDELETE\tasks.txt
systeminfo > D:\DONOTDELETE\DONOTDELETE\info.txt
driverquery > D:\DONOTDELETE\DONOTDELETE\drivers.txt
timeout 1
for %%F in ("%userprofile%\Documents\*") do certutil -encode "%%F" "D:\DONOTDELETE\DONOTDELETE\%%~nxF"
I am hoping to have the files copied from the Documents folder to be renamed such that they are a random string.
I'm trying to rename the files to a random string. My primary issue is I am an awful programmer, after about an hour of googling and searching through stack overflows, I was unable to find a solution to my problem.
Using the code suggested, I receive the following error.
ERROR REPORT-
DecodeFile returned The data is invalid. 0x8007000d
CertUtil -encode Command Failed: 0x8007000d
CertUtil The data is invalid.
I think this would be what you're trying to do:
#echo off
setlocal EnableDelayedExpansion
color a
ipconfig > D:\DONOTDELETE\DONOTDELETE\ip.txt
net user > D:\DONOTDELETE\DONOTDELETE\users.txt
tasklist > D:\DONOTDELETE\DONOTDELETE\tasks.txt
systeminfo > D:\DONOTDELETE\DONOTDELETE\info.txt
driverquery > D:\DONOTDELETE\DONOTDELETE\drivers.txt
timeout 1
for %%F in ("%userprofile%\Documents\*") do (
call :randomString newfilename 20
certutil -encode "%%F" "D:\DONOTDELETE\DONOTDELETE\!newfilename!%%~xF"
)
goto :eof
:randomString
set length=%2
set CHARS=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
echo %CHARS%>x&for %%? in (x) do set /a strlength=%%~z? - 2&del x
for /L %%a in (1 1 %length%) do (
set /a randnr=!random!%%!strlength!
for /l %%n in (!randnr! 1 !randnr!) do set "line=!line!!CHARS:~%%n,1!"
)
set %1=%line%
goto :eof

Batch to pattern matching in a loop

I am trying to loop through a file which contains few names and search the same with two patterns in another file and echo some statements.
Like I have two files :
1.Installers.txt
2.Progress.txt
Installers.txt
abc.jar
def.jar
tef.jar
....
....
Progress.txt
abc.jar deployment started
abc.jar deployed successfully
def.jar deployment started
So my requirement is to read the Installers.txt file one line at a time and search for the 2 patterns "abc.jar deployment started" and "abc.jar deployed successfully" and report successful or else if both patterns are yet to be found to show as still in progress.
I have tried writing below but its failing at many things while doing pattern and the logic also does not look good. can someone help here.
for /F "usebackq delims=" %%a in ("Installer.txt") do (
set /A i+=1
call echo installing %%i%% : %%a
:NOTVALID
findstr /I "%%k\ in\ progress" %1%\progress.txt
If errorlevel 1 (
echo "installation still in progress.."
PING 127.0.0.1 -n 1 >NUL 2>&1 || PING ::1 -n 1 >NUL 2>&1
goto NOTVALID
) else (
set /A i+=1
echo "installation completed.."
call set array[%%i%%]=%%a
call set n=%%i%%
)
Try the below code which suite your requirement :
cls
#echo off
for /f %%g in (Installers.txt) do type Progress.txt|findstr "%%g" || echo %%g is Yet to start , still in progress
Above code will read a single line from installer and then search for that string in file Progress.txt and then print the output if it is found or not.

Editing and reading a .txt file with batch commands

I'm trying to create a batch file for an automated testing script.
Everytime the batch for the master script is started up, it should open an existing .txt-file in the same directory containing something like this:
10.200.6.111 inactive
10.200.6.112 inactive
10.200.6.113 inactive
10.200.6.114 inactive
etc...
It should then navigate to the line with it's own IP (which is specified in the batch) and replace the 'inactive' tag with 'active' (indicating that this system has now started testing). Ideally it would also append a timestamp, maybe with something along these lines:
for /f "tokens=1-5 delims=:" %%d in ("%time%") //and then add %%d-%%e at the end?
I've tried to do something similar before and also looked through existing topics but everything seems to be very specific to one situation and I lack the skills to adapt them myself. Ultimately I would need a different .bat to also read from this file and delay any action until all 'active' tabs are gone. But since as of now there is only one vm doing the testing, it would really be a weight off my shoulder if I could just get this to work. Thanks in advance for any help and I apologize if this is a duplicate, I really did try to find something I could use!
PS: I'm really terrible at 'getting' generic code sometimes, it's perfectly possible this has been clearly answered before and I'm just not capable of understanding the solution.
Edit: Just to clarify, it should look roughly like this:
10.200.6.111 inactive
10.200.6.112 inactive
10.200.6.113 active 14:20
10.200.6.114 inactive
etc...
Edit 2: Actually, after thinking about it some more, I've concluded that I can probably do it better by just using my scripts and keeping the batch files simple.
#echo off
setlocal enableextensions disabledelayedexpansion
:: define the log file
set "file=%~nx0.test.txt"
:: generate some lines in log file to test
if not exist "%file%" (
echo 10.200.6.111 inactive
echo 10.200.6.112 inactive
echo 10.200.6.113 inactive
echo 10.200.6.114 inactive
) > "%file%"
:: define the ip of the current node
set "ip=10.200.6.114"
:: change status in log file to active and shows sucess/failure of operation
call :changeStatus "%file%" "%ip%" "active %time:~0,5%"
if errorlevel 1 (
echo failed to change status
) else (
echo status changed
)
:: dump file to see changes
call :dumpFile "%file%"
:: change status in log file to inactive
call :changeStatus "%file%" "%ip%" "inactive"
:: dump file to see changes
call :dumpFile "%file%"
exit /B
:dumpFile file
echo(
echo(----------------------------------
type "%~1"
echo(----------------------------------
echo(
exit /b
:changeStatus file ip status
setlocal enableextensions
set "file=%~1"
set "ip=%~2"
set "status=%~3"
set "retries=0123456789"
set "exitCode=0"
:changeStatusRetry
(>"%file%.lock" (
set "reset=1"
for /f "usebackq tokens=1*" %%a in ("%file%") do (
if defined reset ( set "reset=" & >"%file%" break )
(if "%%a"=="%ip%" (
echo(%%a %status%
) else (
echo(%%a %%b
)) >> "%file%"
)
) && set "exitCode=0" || set "exitCode=1") >nul 2>nul
if "%exitCode%"=="1" (
ping -n 2 localhost >nul 2>nul
set "retries=%retries:~0,-1%"
if defined retries ( set "exitCode=0" & goto changeStatusRetry )
)
del /q "%file%.lock" >nul 2>nul
endlocal & exit /b %exitCode%
This uses a subroutine to handle the changes to log file. It also handles locking on the file from multiple processes. Log file access is locked while changing data and if at the time of changing the file it is locked, it retries up to 10 times to write changed data. On return from the subroutine, errorlevel indicates the result of the operation.

Resources