BAT多个For循环可进一步过滤结果

时间:2019-05-31 17:16:58

标签: batch-file for-loop findstr

我正在设置一个bat脚本,该脚本按使用的端口(5432、5433等)列出所有postgres安装,并允许用户选择安装。我将netstat转换为txt,然后使用 for 循环读取以过滤结果

到目前为止还不错,但是问题是我无法按自己的喜好缩小结果范围。我希望生成的列表是这样的:

5432
5433
5434
etc

这就是我正在使用的:

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 )

这是“ 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

这是由 for 循环过滤的netstat:

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

我对如何进一步过滤结果感到困惑。我用“ -b”生成netstat,因为我想知道什么.exe使用了哪些端口。

是否可以将 for 循环? for 中的 for ,这样我可以进一步缩小结果的范围吗? 例如,如果我可以运行 for

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

由于lop.txt具有前一个 for 的输出,因此我最终得到:

5432
postgres
5432
postgres
5939
49680
49680

哪个更接近我想要的。我只需要“以某种方式”过滤掉其下一行没有“ postgres”的结果,并找到一种忽略重复值的方法,例如不列出两个5432。知道我该怎么做吗?

1 个答案:

答案 0 :(得分:0)

@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

在测试中,我使用了一个名为q56399294.txt的文件,其中包含您的netstat数据。

首先,清除所有以#开头的变量,然后分析netstat的输出(我假设每一行都以空格开头,如前所述),然后选择第一个和第三个标记(注意{{1 }}已更改为包含空格)。当前一行的端口记录为# port 时,应该将端口分配给DELIMS,然后将其分配给%%q,除非第一个标记是candidate。最后,报告设置的所有#端口