在shell脚本中解析wmic的输出

时间:2013-10-13 19:20:38

标签: java windows shell batch-file batch-processing

我正在尝试解析WMIC的输出,然后获取PID。

我的脚本如下:

@echo off

setLocal enableExtensions enableDelayedExpansion

FOR /F "tokens=1* delims=" %%A IN ('"wmic process where(name="java.exe") get ProcessID,commandline| FINDSTR /v "CommandLine" | FINDSTR "TestServer""') DO (
     set "line=%%A"
     @REM echo "%%A"
     for /F "tokens=* delims= " %%C in ("%%A") do (
         echo "%%C"
         echo "%%D"
  )
)

输出如下:

"java  com.test.TestServer                                       7560       "
"%D"
"java  com.test.TestServer                                       7380       "
"%D"

我的目标是获取进程ID。

我已尝试将space作为FOR循环中的delims。但没有运气。

所以我的问题是如何格式化WMIC的列并获取列?

4 个答案:

答案 0 :(得分:2)

WMIC使用SQL语法的子集。您可以通过使用带有%的LIKE运算符作为通配符,在功能上将FINDSTR测试放入WMIC WHERE子句中。由于它是在批处理脚本中,%需要加倍。

解析ProcessID要容易得多,因为WMIC输出中不再需要CommandLine值。我添加了SessionID,在末尾放置一个未使用的值,以便更容易解析值,而不必担心FOR / F在将WMIC unicode输出转换为ANSI时会以某种方式引入的不需要的回车符。

@echo off
setlocal
set "pid="
for /f "skip=1" %%A in (
  'wmic process where "name='java.exe' and commandline like '%%TestServer%%' and not commandline like '%%CommandLine%%'" get processid^, sessionid'
) do if not defined pid set "pid=%%A"

编辑回应评论中的问题

WMIC unicode的FOR / F转换还会引入看似空的但实际上包含单个回车符的不需要的行。在我上面的代码中,我假设您期望单行,因此我使用IF DEFINED来有效地忽略不需要的尾随“空白”行。

如果您期望多个值,则需要另一种方法。额外的FOR / F循环将删除不需要的回车符,因此行真正变空,因此被忽略。根据您的评论,您似乎不再需要忽略包含“CommandLine”的命令行。

我不知道你需要对这些值做什么,所以下面的代码只是回显每个值。我使用SKIP = 1代替通过FINDSTR管道结果以避免标题行。

@echo off
for /f "skip=1" %%A in (
  'wmic process where "name='java.exe' and commandline like '%%TestServer%%'" get processid'
) do for /f %%B in ("%%A") do echo %%B

答案 1 :(得分:0)

使用tokens = *

时,将忽略delims参数

当您需要第三个令牌时,您应该使用token = 3

答案 2 :(得分:0)

这在我的系统上起作用,以获得单个运行过程的PID。

@echo off
FOR /F %%A IN ('"wmic process where name="java.exe" get ProcessID,commandline |findstr [0-9] " ') DO echo "%%A"
pause

答案 3 :(得分:0)

for /f "tokens=1*delims==" %%a in ('wmic process where 'name^="java.exe" AND CommandLine like "%%TestServer%%"' get ProcessID /format:list^|find /i "ProcessID"') do set "ProcessID=%%b"
echo %ProcessID%