Is there a way to change command-line output before saving to a file?

310 Views Asked by At

I'm writing a program that uses the "tracert" command to find traceroutes for IP addresses, which I'll then use to do some things with.

How I had planned to do this is, is by dumping the output for all IP addresses into a text file by appending with >>output.txt and then reading it in with Python or something and turn it into something usable.

My issue with this is that tracert also shows in its output some things that are of no use to me, such as the first line that says where it's tracing to and what the maximum number of hops is, or the last line that only says: "Trace complete".

The thing is that I'm going to be tracing 3500+ IP addresses, and that number is only going to grow, so that is a whole lot of text that I'm printing in a file that is absolutely useless.

That's why my question is: Is there any way that I can modify the output of the command before saving it, in a batch file?

The command I'm running:

tracert -h 30 -w 500 XX.XXX.XXX.XX >>cmd_output.txt

The output it gives:

Tracing route to XYZ.net 
[XX.XXX.XXX.XX]
over a maximum of 30 hops:

  1    41 ms    18 ms     2 ms  text.net [XXX.XXX.XXX.X] 
  2     2 ms     1 ms     1 ms  text.net [XX.XXX.XXX.XXX] 
  3     1 ms     1 ms     1 ms  text.net [XX.XXX.XXX.XXX] 
  4     5 ms     5 ms     5 ms  text.net [XXX.XX.XX.XXX] 
  5     5 ms     5 ms     5 ms  text.net [XXX.XX.XX.X] 
  6    25 ms    25 ms    25 ms  XYZ.net [XX.XXX.XXX.XX] 

Trace complete.
4

There are 4 best solutions below

0
On

Using your replies and some more searching, I have come up with this solution:

@echo off
rem token 1 is hop-number
rem token 6,7 or 8 may be IP, depending on whether 2 or less requests dont receive a response.
for /f "tokens=1,6,7,8 delims=* " %%a in ('tracert -d -h 30 -w 350 8.8.8.8^|findstr /bc:" " ') do (
  echo %%a, %%b, %%c, %%d
  )>>ips.txt
endlocal

This yields the following response:

1, <1, ms, 192.168.1.240
2, 1, ms, 195.114.237.65
3, 1, ms, 94.247.72.33
4, <1, ms, 82.150.154.129
5, 1, ms, 217.170.0.244
6, 2, ms, 193.239.117.142
7, 2, ms, 108.170.241.140
8, 2, ms, 216.239.41.49
9, 5, ms, 74.125.37.130
10, 209.85.243.253, , 
11, 5, ms, 108.170.237.135
12, , , 
13, 5, ms, 8.8.8.8

In each line, before the first comma is always the hop-number. Then the IP address may be after the first, second or third comma. Since tracert sends three requests per hop one, two or three of those requests can fail.

If a request fails, the result is "*", instead of "X ms" and because I'm delimiting with spaces, if I would always take the 8th token, it might not contain the IP address, or anything for that matter.

This code will always contain the IP address, but will still contain some superfluous data if fewer then two requests failed, because then token 6 and or 7 will contain some part of "X ms".

In the response, you'll see all requests were successful, except for hop 10, where two requests failed and hop 12, where three requests failed and thus tracert failed to return an IP address.

If anyone has any bright ideas on how to remove these last bits of superfluous data, it would be appreciated. Otherwise this is a perfectly workable output for me. So thanks for your help! :)

0
On
@echo off
setlocal enabledelayedexpansion
for /f "tokens=1,*" %%a in ('tracert -d -h 30 -w 350 8.8.8.8 ^|findstr /bc:" "') do (
  for %%c in (%%b) do set ip=%%c
  set ip=!ip:[=!
  set ip=!ip:]=!
  echo !ip!|findstr "[0-9]" >nul || set "ip=-"
  echo %%a, !ip!
)

the second for (%%c) gets the very last word of the line (which is either an IP address or an IP address in brackets or the last word of "Request timed out." (out. in English Windows versions). The rest of the lines is just to beautify the result (removing brackets, replacing anything that has no number (is no IP address) with a -

Maybe you want to replace the two echo ... lines with just:

  echo !ip!|findstr "[0-9]" >nul && echo %%a, !ip!

This wouldn't output lines without an IP address.

For the && and || thingy, see SS64

For the !variable! syntax see delayed expansion

0
On

Maybe the following helps, I believe you can you use it and adjust it to your own use: Batch - Parsing the output of Tracert

0
On

The exact formula to skip the N first lines from one command's output is:

for /f "skip=N tokens=*" %a in ('<command>') do @echo %a

In your case:

for /f "skip=4 tokens=*" %a in ('tracert -h 30 -w 500 XX.XXX.XXX.XX ') do @echo %a >> cmd_output.txt