Example:
:loop
set n=0
set m=254
set /a n+=1
ping -n 1 -w 500 xxx.xxx.xxx.%n% | find /i "reply" > file
=====BELOW is what I need=====
set a=0
set /a a+=1
set %a%= < file
====ABOVE is what I need=====
if %n% lss %m% goto loop
So specifically I need a batch script that can make number of variables as much as he loops. I searched a lot for answer and even tried few ideas on my own... but I can't figure this out... I guess lack of batch knowledge since I am ubuntu user and not Win. Thanks in advance. Regards
Use FOR /L instead of SET /A with GOTO
Use FOR /F to process results of command instead of temp file and SET /P
Use carefully constructed variable names to emulate an array (potentially sparse array in this case)
for /l %%N in (1 1 255) do (
for /f "delims=" %%A in (
'ping -n 1 -w 500 xxx.xxx.xxx.%%N^|find /i "reply"'
) do set "addr[%%N]=%%A"
)
#echo off
setlocal enableextensions disabledelayedexpansion
for /l %%n in (1 1 254) do (
for /f "tokens=*" %%r in (
'ping -n 1 -w 500 xxx.xxx.xxx.%%n ^| find "reply" '
) do set "a[%%n]=%%r"
)
set a[
endlocal
This uses for /f to run a command (ping | find) and assing the output of the command (1 line of the ping response, filtered by find) to a variable with a incrementing number in its name.
set a[ is used to show the resulting data on console
#echo off
if exist Pingresult.txt del Pingresult.txt
for /l %%n in (1 1 254) do ping -n 1 -w 500 xxx.xxx.xx.%%n | find /i "reply" >>PingResult.txt
Related
I currently have a batch file that is going through a text file and assigning each line into an array. I want to iterate through the loop and remove a certain number of characters from every value in the array. Is this possible to do?
#ECHO off
findstr /C:"number" /C:"type" testFile.txt > oneresult.txt
set "file=oneresult.txt"
set /A i=0
timeout /t 1
echo ---------------Results--------------- > results.txt
for /f "tokens=*" %%x in (oneresult.txt) do (
call echo %%x >> results.txt
call set array[%i%]=%%x
set /A i+=1
)
call echo %i% files received >> results.txt
del "oneresult.txt"
So right now it just prints the retrieved strings from testFile.txt and then they are eventually placed into result.txt. I would like all the strings that come from the testFile.txt to have the first 10 characters removed. If there is an easier way please let me know. So far this is what I have found but I am also a bit of a batch noob.
Just figured it out without the array and posting the answer for anyone else that may be searching in the future:
#ECHO off
findstr /C:"number" /C:"type" testFile.txt > oneresult.txt
set /A i=0
timeout /t 1
echo ---------------Results--------------- > results.txt
for /f "tokens=*" %%x in (oneresult.txt) do (
setlocal enabledelayedexpansion
call set print=%%x
call set newprint=!print:~32!
call echo !newprint! >>results.txt
endlocal
set /A i+=1
)
call echo %i% files received >> results.txt
del "oneresult.txt"
You use several call's in your code without having understood that these pseudo calls are usually used for a different type of delayed expansion not requiring setlocal enabledelayedexpansion, but to double the percent signs.
the intermediate file oneresult isn't necessary, one for /f to parse the output of the findstr is sufficient.
One set of parentheses enclosing all output lines can redirect to results.txt
#ECHO off
set /A i=0
(
echo ---------------Results---------------
for /f "tokens=*" %%x in (
'findstr /C:"number" /C:"type" testFile.txt'
) do (
set print=%%x
call echo:%%print:~32%%
set /A i+=1
)
call echo %%i%% files received
) > results.txt
The following code with setlocal enabledelayedexpansion is functional identical
#ECHO off&Setlocal EnabledelayedExpansion
set /A i=0
(
echo ---------------Results---------------
for /f "tokens=*" %%x in (
'findstr /C:"number" /C:"type" testFile.txt'
) do (
set print=%%x
echo:!print:~32!
set /A i+=1
)
echo !i! files received
) > results.txt
I have a script to continuously ping a set of machines (stored in SiteName.txt) and once a machine comes online, a counter increments, and the machine is removed from the list so it doesn't ping again (I just need to know if a machine has been online, not if it's on right now).
The issue I have is I've noticed there are a few phantom pings coming up with the IP address of the site they were built at (and that IP hasn't already been taken over by another machine) so I get false positives.
My current code is:
#echo off & setlocal EnableDelayedExpansion
TITLE %~n0
set /a counteron=0
for /F %%a in (%~n0.txt) do set "NVC=!NVC! %%a"
:ping
ping -n 61 127.0.0.1>nul
for %%i in (%NVC%) do (
ping %%i -n 1 | find "TTL=" >nul
if !errorlevel! GEQ 1 (
echo %%i is offline.
) else (
set /a counteron+=1
echo %%i is online
set "NVC=!NVC: %%i=!"
)
)
echo.
cls
echo. %counteron% machines are online.
if defined NVC goto :ping
cls
echo All machines in %~n0 are online.
pause
Is it possible to do the same thing, but if the IP's first 3 octets match a specific set (10.79.208.xxx), then it still comes up as offline?
Thanks in advance
Perhaps
ping %%i -n 1 | find "TTL=" |findstr /b /l /v /c:"Reply from 10.79.208." >nul
which should set errorlevel to zero only if both TTL= is found AND a line beginning (/b) with the /l literal string /c: "Reply from 10.79.208." is /v not found
which I believe is your quest...
Perhaps this slight alteration to your script is what you're after.
#echo off & setlocal enabledelayedexpansion
set nvc=192.168.1.1
for %%i in (%NVC%) do (
ping %%i -n 1 | find "TTL=" >nul
if !errorlevel! GEQ 1 (
echo %%i is offline.
) else (
for /f "tokens=1,2,3 delims=." %%j in ("%%i") do (
set octets=%%j.%%k.%%l
if "!octets!"=="10.79.208" (
echo %%i is false positive
) else (
set /a counteron+=1
echo %%i is online
set "NVC=!NVC: %%i=!"
)
)
)
)
I have a list of 25 websites in a text file, each on an individual line, I would like to open them in random order via a batch file.
websites.txt
...
google.com
facebook.com
...
I know I need to use a for loop, but am not sure how to pull the website address from a random line. I thought of using...
for /f "tokens=%rannum%"
but all the websites would have to be on the same line and from my testing that did not work well. There would also need to be a way to make sure the same website is not opened twice.
What I have so far...
#echo off
set file=openweb.txt
set /a total_lines=1
for /f %%a in ('Type %_File%^|Find "" /v /c') Do Set /a total_lines=%%a
set /a start_count=0
set "found=found.txt"
if exist "%found%" del "%found%"
copy NUL found.txt
if %start_count% NEQ %total_lines% (
:run_again
REM Randomly select a number between 1-26
set /a random_number=%random% %% 26-1
REM Validation Random number was not used already
findstr /m "%random_number%" %found%
if %errorlevel%==0 (
echo already found
goto:run_again
)
REM Open each website. Wait 2sec between each.
for /f %%a in (websites.txt) do (
start iexplore %%a
#ping 127.0.0.1 -n 2 -w 1000 > nul
)
REM write out Random Number to the .txt
#echo %random_number%>>%found%
set /a start_count+=1
)
Any input on how to make this code better is welcome. Thank you
Try this:
#echo off
set file=openweb.txt
set /a lines=25
set /a skip=%random%%%lines%-1
more %file% +%skip% > temp.tmp
set /p target=< temp.tmp
del temp.tmp
Echo %target%
I'm doing a simple ping bandwidth test in batch to get speed in kb/s and I've run into a problem with the ms trailer after the average round trip time 123ms. The batch can't deal with the letters in the number token and it has no space to set another token with. I've looked at several solutions using delims= but did not success. I'm stuck and can't do anything except manually enter the number to get bandwidth. I'm running Windows XP and don't want to use anything but batch, i.e. no VBS, Java, hybred bat, etc. If it can't be done with simple command line I'll just manually enter the number and be done with it. Here is my batch:
#echo off
color 0b
MODE CON:COLS=57 LINES=15
for /F "tokens=9" %%a in ('ping -n 1 -l 1024 8.8.8.8^| find "Average"') do set "A1=%%a"
echo %A1%
set /a T=%A1%
set /a varia=1000/%T%
set /a answer=%varia%
set /a varia2=%answer%
set /a answer2=%varia2%
echo.
echo Speed %answer2% Kb/s
pause
and this from a answer here on stackoverflow
#echo off
color 0b
MODE CON:COLS=57 LINES=15
for /f "tokens=9 delims=()" %%a in (
'ping -n 1 -l 1024 8.8.8.8^| find "Average"'
) do (for /f "tokens=9" %%b in ("%%a") do (
set num=%%b & set num=!num:%%=!
if !num! == !num! goto nc
)
)
:nc
echo !num!
set /a T=!num!
set /a varia=1000/%T%
set /a answer=%varia%
set /a varia2=%answer%
set /a answer2=%varia2%
echo.
echo Speed %answer2% Kb/s
pause
Test this in XP: it works in Win 8.1
for /F "tokens=8 delims=ms=, " %%a in ('ping -n 1 -l 1024 8.8.8.8^| find "Average" ') do set "A1=%%a"
Ok, I have been playing around with this for a while and am getting no where. I need to pull the KB number out from a line.
The issue i am having is that some of the KB numbers are 6 characters and some are 7, and can't seem to find a way that will work to error detect the two.
The Two types of errors this makes is as follows
The First one should only have been displayed 6 characts so it added the extra "-" at the end.
x64 KB890830- 2012\MS12-000\WinSec-KB890830-006-P58310-Windows-KB890830-x64-V4.9.exe
While the second error shows the random "_" because it uses the first KB shown not the second.
ia64 KB_942288 2012\MS12-000\WinSec-KB_942288-007-P58312-WindowsServer2003-KB942288-v4-ia64.exe
EDIT
Batch File So Far
#ECHO OFF
SETLOCAL enableDelayedExpansion
IF EXIST Export.csv DEL Export.csv
FOR /F "tokens=*" %%I in ('dir /s /b *.*') DO CALl:Generate "%%I"
pause
:Generate
SETLOCAL
IF "%~x1" NEQ ".exe" (
If "%~x3" NEQ ".msu" (
GOTO:EOF
)
)
CALL:FindArchitecture %1
CALL:FindKB %1
CALL:PathFix %1
ECHO %Architecture%,%KB%,%FilePath%>>Export.csv
CALL:Cleanup
ENDLOCAL
GOTO:EOF
:FindArchitecture
ECHO %1 | FINDSTR "x64"
IF "%ERRORLEVEL%"=="0" (
SET Architecture=x64
SET Count+=1
)
ECHO %1 | FINDSTR "x86"
IF "%ERRORLEVEL%"=="0" (
SET Architecture=x86
SET Count+=1
)
ECHO %1 | FINDSTR "ia64"
IF "%ERRORLEVEL%"=="0" (
SET Architecture=ia64
SET Count+=1
)
IF "%Count%" GTR "1" (
SET Architecture=Error
)
SET Count=0
GOTO:EOF
:FindKB
set KBNum="%~1"
set "KBNum=!KBNum:*-KB=!"
ECHO !KBNum!|findstr /I /E /R /c:"-KB[0-9][0-9][0-9][0-9][0-9][0-9][0-9]" >nul
SET "KB=KB!KBNum:~0,7!"
IF "%KB%" NEQ "" GOTO:EOF
ECHO !KBNum!|findstr /I /E /r /c:"-KB[0-9][0-9][0-9][0-9][0-9][0-9]" >nul
SET "KB=KB!KBNum:~0,6!"
GOTO:EOF
:PathFix
set Path_to_convert=%~1
set Reference_path=%~dp0
set FilePath=!Path_to_convert:*%Reference_path%=!
GOTO:EOF
:Cleanup
SET KBNum=
SET KB=
SET Count=
SET Architecture=
set InstallerPath=
set PathRemoval=
set Path=
GOTO:EOF
OK - siginificant edit after seeing comments from Ken White and the OP.
I'm not sure if you need this, but FINDSTR with a regular expression can validate that the line has the pattern: "-KB" followed by 7 digits, followed by "-".
echo somestring|findstr /r /c:"-KB[0-9][0-9][0-9][0-9][0-9][0-9][0-9]-" >nul
Then use substitution to remove everything from the beginning through "KB-".
Then use FINDSTR to verify that the first 7 remaining characters are digits. If not, then loop back and replace up to the next "-KB", etc.
Then you just need to take the first remaining 7 characters.
#echo off
:parseVal
setlocal enableDelayedExpansion
set val="%~1"
echo !val!|findstr /r /c:"-KB[0-9][0-9][0-9][0-9][0-9][0-9][0-9]-" >nul || (
echo Invalid format - KB value not found
exit /b
)
:parseVal2
set "val=!val:*-KB=!"
echo !val!|findstr /brc:"[0-9][0-9][0-9][0-9][0-9][0-9][0-9]-" >nul || goto :parseVal2
set "val=KB!val:~0,7!"
echo val=!val!
exit /b
EDIT
I'm not sure what you did to accept the 6 digit numbers, but the following regex expressions will work with numbers of any length.
For the 1st regex: findstr /rc:"-KB[0-9]*-"
For the 2nd regex: findstr /brc:"[0-9]*-"
Then you can use either of the following to extract out the number when you don't know the length:
for /f "delims=-" %%A in ("!val!") do set "val=KB%%A"
or
set val=KB%val:-=&REM %"