批处理命令 - 在单独的行中查找多个文本并将其作为列输出

时间:2017-01-27 05:34:56

标签: batch-file for-loop text

我正在尝试按照reg命令

列出域PC中已安装软件的清单

Reg Query HKLM \ Software \ Microsoft \ Windows \ CurrentVersion \ Uninstall / S ^ |查找/我" DisplayName"

我正在使用Find / I" DisplayName"获得软件名称。我还需要版本号(稍后可能会有更多字段),但它在另一行中作为DisplayVersion。

由于我在多台计算机上运行此脚本,因此我的脚本如下所示:

    for /f %%i in (computers_ALL.txt) do (

for /f "tokens=1,2,*" %%j in ('psexec \\%%i Reg Query HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall /S ^| Find /I "DisplayName"') do (
    echo x64 %%i %%l >>%OUTPUT_FILE%
    )

for /f "tokens=1,2,*" %%j in ('psexec \\%%i Reg Query HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /S ^| Find /I "DisplayName"') do (
    echo x86 %%i %%l >>%OUTPUT_FILE%
    )
)

现在我只能找到DisplayName。如何找到另一行上的DisplayVersion并将其添加到第二列?我的输出就像,

ComputerName,Platform(32-64位),软件名称,软件版本

我可以注意软件名称,但很难获得版本并将其放在第二列。感谢您的帮助。感谢。

2 个答案:

答案 0 :(得分:0)

@ECHO OFF
SETLOCAL
SET "output_file=u:\report.txt"
DEL "%output_file%" /F /Q
for /f %%i in (q41887529.txt) do (
 SET "compname=%%i"
 CALL :clrsoft
 FOR %%z IN (\ \Wow6432Node\) DO ( 
  for /f "tokens=1,2,*" %%j in (
   'Reg Query HKLM\Software%%zMicrosoft\Windows\CurrentVersion\Uninstall /S ^| Findstr /I "DisplayName DisplayVersion HKEY_LOCAL_MACHINE\\"'
   ) do (
    IF /i "%%j"=="Displayname" (
     SET "softname=%%l"
    ) ELSE (
     IF /i "%%j"=="Displayversion" (
      SET "softver=%%l"
     ) ELSE (
      CALL :report %%z
    )
   )
  )
 REM processed all data - final report
 CALL :report %%z
 )
)

GOTO :EOF

:: Report routine parameters : 
:: %1 indicates x64 ("\") or x86 (\Wow6432Node\)

:report
IF NOT DEFINED softname GOTO clrsoft
IF "%1"=="\" (
 ECHO "%compname%",x64,"%softname%","%softver%">>"%output_file%"
 ) ELSE (
 ECHO "%compname%",x86,"%softname%","%softver%">>"%output_file%"
)
:clrsoft
SET "softname="
SET "softver="
GOTO :EOF

当然,您需要设置自己的输出文件名。我还删除了psexec \\%%i并在q41887529.txt中设置了我的计算机名称,以便在我的计算机上进行测试。

由于查询之间的唯一区别是节点,因此我合并了这些步骤并使用%%z控制它们。

清除tempvars,然后处理三个目标字符串之一的每个返回行。

如果它是一个名称,则调用:report报告任何累积的数据,然后记录名称

如果它是版本,请记录版本,因为现在应该给我们一对,报告它。

如果它既不是,那么它必须是一个新密钥,所以报告我们到目前为止所拥有的。

瑕疵是版本不存在 - 最终条目可能是无版本的,所以我们再次尝试报告以确保输出任何累积的数据。

我现在修改了这个并取代原来的。

它将报告从文件中提取的机器名称,并且我认为经常丢失的版本号已经修复 - 名称和版本的顺序是不可预测的,因此报告是使用{{的实例之间累积的数据触发的。 1}}并且在最后。

答案 1 :(得分:0)

以下脚本适用于本地Windows计算机。将其调整为列表computers_ALL.txt而不是"%computername%"并添加psexec \\%_comp%应该是一项简单的任务。

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "OUTPUT_FILE=%temp%\41887529.txt"
for /F %%i in ("%computername%") do (
  set "_comp=%%i"
  call :proHive "x64" "\Software\Microsoft\Windows\CurrentVersion\Uninstall"
  call :proHive "x86" "\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
)

rem debugging output
type "%OUTPUT_FILE%"
ENDLOCAL
goto :eof

:proHive
rem %1 platform
rem %2 registry key
>>"%OUTPUT_FILE%" (
for /f "tokens=*" %%G in ('
  Reg Query "HKLM%~2" /S /V DisplayName ^| Find /I "HKEY_LOCAL_MACHINE%~2"
  ') do (
    set "_DisplayName="
    set "_DisplayVersion="
    for /f "tokens=1,2,*" %%j in ('
      Reg Query "%%G" ^| Findstr /I "DisplayName\> DisplayVersion\>"') do set "_%%j=%%l"
    SETLOCAL EnableDelayedExpansion
      echo %_comp%,%~1,!_DisplayVersion!,!_DisplayName!
    ENDLOCAL
)
)
goto :eof