Store multiple lines in a variable - windows

I need to save a filtered multi-line output into a single batch variable but so far without success.
I can't use Powershell in this stripped down version of POS Terminal and the use of a temporary file is impracticable because the OS runs from a ultra slow SD card.
With this, I need the following output in a single variable:
C:\Users\medUser> route print | findstr "127 10 192"
127.0.0.0 255.0.0.0 On-link 127.0.0.1 331
127.0.0.1 255.255.255.255 On-link 127.0.0.1 331
127.255.255.255 255.255.255.255 On-link 127.0.0.1 331
224.0.0.0 240.0.0.0 On-link 127.0.0.1 331
255.255.255.255 255.255.255.255 On-link 127.0.0.1 331
In this case, I need to capture this 5 lines (but in reality will be more than 15) as displayed into a single variable.
Is it possible without resorting to external tools?
I'm aware of some approaches like this, this, or this, but I'm unable to make it work.
I've tried the solution bellow, but unfortunately it only stores the last line.
FOR /F "tokens=* USEBACKQ" %F IN (`route print ^| findstr "127\."`) DO (SET var=%F)
ECHO %var%
Note: The end goal is to have a big string that I can parse multiple times through findstr without heaving to run the same command over and over again.
If not feasible, I'll also accept a solution where a variable has a counter, like var1 for the first line, var2 for the second, etc. Thanks!
Inefficient sample code in use:
:loop
SET _ror2="NOK"
route print | findstr "10\.16\.0\.0.*255\.255\.0\.0.*10\.147\.1\.3" && route print | findstr "192\.168\.47\.0.*255\.255\.255\.0.*192\.168\.46\.3" && route print | findstr "10\.16\.0\.0.*255\.255\.0\.0.*10\.147\.1\.3" && route print | findstr "xxxxx" && route print | findstr "repeat with 15 more conditions to test" && SET _ror2=ok
if "%_ror2%" == "ok" (
timeout 20 >NUL
goto loop
)
ECHO One of our 15 comparisons above wasn't found, hence re-apply routes
route change 10.16.0.0 mask 255.255.255.0 10.147.1.3 metric 10
route change 192.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
route change xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Your idea with numbered variables is not that bad:
#echo off
setlocal enabledelayedexpansion
REM get the output into numbered variables:
set i=1
for /f "delims=" %%a in ('route print^|findstr "127 10 192"') do (
set /a i+=1
set "_myvar_!i!=%%a"
)
ECHO search within those variables:
set _myvar_ |find "127"
ECHO or:
(for /f "tokens=1* delims==" %%a in ('set _myvar_') do #echo %%b) |find "127"
Note: this doesn't keep the order when i>10 (probably not a problem for you)

Related

How to get lines that start with specific word in cmd from a text file?

I was trying to simulate real network with packet tracer. So I get the website URLs in a specific domain and tided them in an ASCII file with file name WebSites-DB line by line like this:
www.google.com
stackoverflow.com
Then I used the command ping to get their IP addresses:
FOR /F "eol=#" %i in (WebSites-DB) do ping %1 -n 1 -w 1 1>> Ips.txt
But ping output multiple lines:
Pinging www.google.com [8.8.8.8] with 32 bytes of data:
Request timed out.
Ping statistics for 185.216.132.250:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
I want only the websites name www.google.com and its IP address 8.8.8.8.
How to get just the data of interest?
use this line:
FOR /F "usebackq tokens=2,3 delims= " %i in (`find "Pinging" Ips.txt`) do #Set "_=%j"&Call Echo %i ^%_:~1,-1^%
it will give result such like:
www.goog.com 8.8.8.8
More info:
substring windows command line

How to do ping `whoami`.google.com in windows?

I want to ping a server with the input of the first command being the the subdomain for the ping command.
In a simple term (Linux way of doing the same thing).
ping `whoami`.google.com
Now I want the same thing in windows CMD. How can I do this?
You would have to parse the WhoAmI from Windows in a FOR /F Loop then use the FOR /F Loop variable in a Ping Command as part of the FOR /F Loop's DO Clause.
You can Dump this directly into CMD:
FOR /F "Delims=\" %_ IN ('
WhoAmI
') DO (
Ping %_.Google.com
)
Or as a single line (which is easier to re-run by hitting the UP arrow)
FOR /F "Delims=\" %_ IN ('WhoAmI') DO ( Ping %_.Google.com )
Assuming your domain is "Contoso.com" the Result is you ping Contoso.Google.com If you domain is "Adventureworks.Contoso.com" you ping AdventureWorks.Google.com

PING w/ TIMESTAMP &

Using the standard windows CMD Prompt, I want to PING an IP "x" amount of times, and get results that are time stamped. The following does the job but it does not give PING STATISTICS at the end AND leave me ready for the next cmd.
ping -n 13 37.48.68.15|cmd /q /v /c "(pause&pause)>nul & for /l %a in () do (set /p "data=" && echo(!date! !time! !data!)&ping -n 2 37.48.68.15>nul"
I believe I am asking for 13 pings, but I only get 11, is there a resolve for that? AND Bonus Points if it will automatically print to a text file!
Photochop-EXAMPLE; http://www.plumbers.cc/images/tanki/cmd-example.jpg

Batch script for checking if a server is online

I basically want to have a windows batch script which goes through a list of servers and checks every server with a ping if it is online.
The list of servers should be a simple plain text file and should look something like this:
...
"Google" www.google.com
"Node1" 221.12.123.1
"Download Server" dl.myserver.com
"Login Server" login.myserver.com
...
Here is a simple rundown what the program should do:
print a list of the descriptions of all the servers in the list to the screen.
ping the first server server 4 times if one ping succeeds it should return online if all 4 pings fail it should return offline.
print online or offline next to the first server in the printed list
run step 2 and 3 for all other servers in the list.
The output should look like the following:
...
Google: online
Stackoverflow: online
Node1: online
Download Server: offline
Login server: offline
...
I just want to know if this is even possible in (windows) batch and how to do it. If it isn't possible in batch, what programming language should I use? Would it be possible to program this in Python?
I would also be really thankful if anybody could post the code how to do this, Thanks!
#echo off
setlocal enableextensions enabledelayedexpansion
for /f usebackq^ tokens^=1^,2^ delims^=^" %%a in ("servers.txt") do (
call :isOnline %%b && set "status=online" || set "status=offline"
echo %%a : !status!
)
endlocal
exit /b
:isOnline address
setlocal enableextensions disabledelayedexpansion
:: a temporary file is needed to capture ping output for later processing
set "tempFile=%temp%\%~nx0.%random%.tmp"
:: ping the indicated address and get errorlevel
ping -w 1000 -n 4 %~1 > "%tempFile%" && set "pingError=" || set "pingError=1"
:: When pinging,
::
:: we get errorlevel = 1 when
:: ipv4 - when any packet is lost. It is necessary to check for "TTL="
:: string in the output of the ping command.
:: ipv6 - when all packet are lost.
:: we get errorlevel = 0 when
:: ipv4 - all packets received. But pinging a inactive host on the
:: same subnet result in no packet lost. It is necessary to
:: check for "TTL=" string in the output of the ping command.
:: ipv6 - at least one packet reaches the host.
::
:: +--------------+-------------+
:: | TTL= present | No TTL |
:: +-----------------------+--------------+-------------+
:: | ipv4 errorlevel 0 | OK | ERROR |
:: | errorlevel 1 | OK | ERROR |
:: +-----------------------+--------------+-------------+
:: | ipv6 errorlevel 0 | | OK |
:: | errorlevel 1 | | ERROR |
:: +-----------------------+----------------------------+
::
:: So, if TTL= is present in output, host is online. If errorlevel is 0
:: and the address is ipv6 then host is online. In the rest of the cases
:: the host is offline.
::
:: To determine the ip version, a regular expresion to match a ipv6
:: address is used with findstr. As it will be only tested in the case
:: of no errorlevel, the ip address should be present in the output of
:: ping command.
set "exitCode=1"
find "TTL=" "%tempFile%" >nul 2>nul && set "exitCode=0" || (
if not defined pingError (
findstr /r /c:" [a-f0-9:][a-f0-9]*:[a-f0-9:%%]*[a-f0-9]: " "%tempFile%" >nul 2>nul && set "exitCode=0"
)
)
:: cleanup and return errorlevel
if exist "%tempFile%" del /q "%tempFile%" >nul 2>nul
endlocal & exit /b %exitCode%
This can be done easily in batch, you just need some for /f loops, echo statements, if statements, goto/call statements and use the ping command.
1.print a list of the descriptions of all the servers in the list to the
screen.
You can use echo statement for this, like echo "Google" www.google.com
2.ping the first server server 4 times if one ping succeeds it should
return online if all 4 pings fail it should return offline.
inside a for /f loop [like for /f "tokens=5 delims==, " %%p in (], you can use the ping command with 4 trys like so ping -n 4 www.google.com
3.print online or offline next to the first server in the printed list
you can use and if statemenet here, like so: if "%status%"=="online" echo Google: online or just echo Google: %status%
4.run step 2 and 3 for all other servers in the list.
You can use a goto or a call statement here (use it like a function), for example: call :server_status_function www.google.com

Script to start traceroute if continuous ping fails, output to log

I want to continuously ping my home public IP address, and if the ping fails automatically do a traceroute to see where it's failing.
I've been trying to follow the comments made here:
http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/efc97c66-60a6-4fd7-8be4-4b454d040ce5
Windows compatible would be preferable, bat or vbs would be best.
From anywhere on the internet I will lose my connection to my home network. From work I have started a ping and when it drops I've done a traceroute and it fails before it gets to my IP.
I need a log file to prove that it is not my modem, or router, or computer.
#echo off
set Address=google.com
:Loop
PING -n 5 127.0.0.1>nul
echo Pinging %Address%
%SystemRoot%\system32\ping.exe -n 1 %Address% | %SystemRoot%\system32\find.exe "TTL=" > NUL >> C:\pingtest\logfile.log
if %ERRORLEVEL% EQU 0 goto :Loop
echo Trace route %Address% at %date% %time% >> C:\pingtest\logfile.log
tracert %Address% >> C:\pingtest\logfile.log
goto Loop
This is what I ended up going with, if anyone else ever needs this. Essentially the "Ping -n 127.0.0.1>Nul" is to add a 5 second counter so that it only pinged the destination every 5 seconds, 5 can be changed to whatever value is needed.
Windows 7 has this problem where a ping may result with something like "reply from 192.168.1.5: Destination host unreachable". So instead of erroring out it gets a reply from itself and not the error level 1.
Instead of looking for Error Level 1 I choose to look for no result for TTL with "%SystemRoot%\system32\ping.exe -n 1 %Address% | %SystemRoot%\system32\find.exe "TTL=" > NUL"
Anyway, I'm sure the other answers here were very similar and may have worked, so I am ranking them up, but marking this as the answer.
Thanks all!
#echo off
set Address=www.google.com
set LogDir=C:\pingtest
md %LogDir%
%SystemRoot%\explorer.exe "%LogDir%"
echo PingTest script to monitor network connection. Control-C to exit.
echo Tests connection by pinging %Address%. Logs to %LogDir%\logfile.log.
echo %date% %time% Initial tracert (trace route) to %Address% >> %LogDir%\logfile.log
tracert %Address% >> %LogDir%\logfile.log
:Loop
REM 5 second delay
PING -n 5 -w 1 127.0.0.1>nul
echo %date% %time% Pinging %Address%
echo %date% %time% Pinging %Address% >> %LogDir%\logfile.log
%SystemRoot%\system32\ping.exe -n 1 %Address% | %SystemRoot%\system32\find.exe "TTL=" > NUL
if %ERRORLEVEL% EQU 0 goto :Loop
echo %date% %time% PING ERROR - Tracing route to %Address%
echo %date% %time% PING ERROR - Tracing route to %Address% >> %LogDir%\logfile.log
tracert %Address% >> %LogDir%\logfile.log
goto Loop
You could make a simple batch file that tries a ping and if it fails does a tracert, eg:
setlocal
set host=www.bigpond.com
set logfile=nettest.log
echo %date% %time%>>%logfile%
ping %host%>>%logfile%
if ERRORLEVEL 1 tracert %host%>>%logfile
endlocal
There's plenty of scope for refinement here.
Then create a scheduled task that runs it every five minutes or whatever suits you.
Alternatively you could include a loop with a 'sleep' in it. There's a poor man's sleep at Sleeping in a batch file that uses:
choice /d y /t 5 > nul
:LOOP
FOR /F "usebackq tokens=1" %%F IN (`ping localhost -n 1 -w 1 ^| find "Request"`) DO (
IF "%%F"=="Request" (
tracert localhost
)
)>>log.txt
FOR /F "usebackq tokens=1-4 delims=:." %%G IN (`echo %time%`) DO IF %G%H GTR 1400 GOTO:EOF
GOTO LOOP
Basically, this states do ping, if it finds a line that has an instance of the word Request (which only appears if you can't ping the address) perform a tracert. The -n and -w switches in PING tell it to jump only once and timeout after 1 second of not getting a response. This is perfectly fine if you are pinging your localhost. The second FOR statement is to have a stopping point. Change the 1400 to a time you wish for the script to stop (in military time of course).
I have just been looking for the same thing to investigate why a VPN keeps dropping on a wired connection, used one of the batch file suggestions above which was great.
Also found a nice little Java App which packages it for you here
Internet Connectivity Monitor
Simple to use and does the job :-)

Resources