BAT 多个 For 循环以进一步过滤结果
BAT Multiple For-loops to further filter results
我正在设置一个 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
这会更接近我想要的。我只需要 "somehow" 过滤掉下面一行没有 "postgres" 的结果,并找到一种忽略重复值的方法,比如不列出两个 5432。知道我怎样才能做到这一点吗?
@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
输出(我假设每一行都以 space 开头,如发布的那样)并选择第一个和第三个令牌(注意 DELIMS
已更改为包含 space)。当上一行的端口记录为#port[=25 时,端口应分配给 %%q
,然后分配给 candidate
,除非第一个标记是 postgres.exe
=].最后,报告任何设置的#端口。
我正在设置一个 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
这会更接近我想要的。我只需要 "somehow" 过滤掉下面一行没有 "postgres" 的结果,并找到一种忽略重复值的方法,比如不列出两个 5432。知道我怎样才能做到这一点吗?
@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
输出(我假设每一行都以 space 开头,如发布的那样)并选择第一个和第三个令牌(注意 DELIMS
已更改为包含 space)。当上一行的端口记录为#port[=25 时,端口应分配给 %%q
,然后分配给 candidate
,除非第一个标记是 postgres.exe
=].最后,报告任何设置的#端口。