Fabio Abreu
Fabio Abreu

Reputation: 45

BAT Multiple For-loops to further filter results

I'm setting up a bat script that lists all postgres installations by port used (5432, 5433, etc) and lets the user choose installation. I netstat into a txt and then read it with a for loop to filter results

So far so good, but the problem is I cannot narrow the results to my liking. I would want the list generated to be like this:

5432
5433
5434
etc

This is what im using:

netstat -bnf -p tcp | findstr "127.0.0.1 post" > C:\anbo.txt 2>&1

for /f "usebackq tokens=2 delims=[:]" %%p in ("C:\anbo.txt") do (echo %%p )

This is the raw output of the "netstat":

  TCP    127.0.0.1:5432         127.0.0.1:51725        ESTABLISHED
 [postgres.exe]
  TCP    127.0.0.1:5432         127.0.0.1:56261        ESTABLISHED
 [postgres.exe]
  TCP    127.0.0.1:5939         127.0.0.1:49833        ESTABLISHED
  TCP    127.0.0.1:49680        127.0.0.1:54677        ESTABLISHED
  TCP    127.0.0.1:49680        127.0.0.1:57445        ESTABLISHED

This is the netstat filtered by the for loop:

5432         127.0.0.1
postgres.exe
5432         127.0.0.1
postgres.exe
5939         127.0.0.1
49680        127.0.0.1
49680        127.0.0.1

I'm stumped on how to further filter the results. I am generating the netstat with "-b" because i want to know which ports are being used by what .exe.

Is it possible to loop for loops? A for within a for, so i could further narrow down results? If i could for example run this for:

for /f "usebackq tokens=1 delims=. " %%s in ("F:\lop.txt") do (echo %%s)

Being that lop.txt has the output of the previous for, i would end up with:

5432
postgres
5432
postgres
5939
49680
49680

Which would be much closer to what i want. I would just need to "somehow" filter out the results which have no "postgres" on the line below them and find a way to ignore repeated values, like not listing two 5432s. Any idea how can I accomplish this?

Upvotes: 0

Views: 229

Answers (1)

Magoo
Magoo

Reputation: 80033

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q56399294.txt"

:: remove variables starting #
FOR  /F "delims==" %%a In ('set # 2^>Nul') DO SET "%%a="

FOR /f "usebackq tokens=1,3 delims=[:] " %%p IN ("%filename1%") DO (
 IF "%%p"=="postgres.exe" (CALL :record) ELSE (SET "candidate=%%q")
)

FOR  /F "delims=#=" %%a In ('set # 2^>Nul') DO ECHO %%a

GOTO :EOF

:record
SET "#%candidate%=Y"
GOTO :eof

I used a file named q56399294.txt containing your netstat data for my testing.

First, clear any variables starting # Then analyse the netstat output (I've assumed every line starts with a space, as posted) and choose the first and third token (note DELIMS has been changed to include space). The port should be assigned to %%q and thence to candidate unless the first token is postgres.exe, when the port from the previous line is recorded as #port. Finally, report any #ports that are set.

Upvotes: 1

Related Questions