将多个注册表转储批量解析为 csv

batch parsing multiple registry dumps to csv

我需要使用注册表转储创建一个 csv,其中键作为标题,值作为 txt 文件中的数据。

将有 5000 多个文件转储到电子表格中以用于报告目的。

我无法访问有问题的机器,我只有带有输出的 txt 文件,所以我只能处理文件中的数据及其情况。如果我可以访问它会更容易,因为我可以使用 REG 查询创建我想要的输出,但这不是一个选项。

我无法安装第 3 方工具或软件。我只有 windows 7 附带的东西。 编辑:如果需要,我可以使用 python 3.4,但我对它的了解非常有限。

用批处理执行此操作的最快和最好的方法是什么? 我有一些批处理知识,但似乎无法掌握这一点。 我只能使用单个注册表的 reg 查询找到解决方案。

有些值可以为空或包含单个字符,这也使它变得棘手。 这是一个 txt 文件中的示例。 headers 和值很重要,可能需要 200 个密钥中的 50 个。

[HKEY_LOCAL_MACHINE\SOFTWARE\INVENTORY\MACHINE]
"WINDOWS"="Microsoft Windows XP [Version 5.1.2600]"
"PROCESSOR"="              Intel(R) Celeron(R) D CPU 3.20GHz"
"SYSPAGEFILE"="1524MB"
"DISPLAY_RES"="800x600"
"CPU_NAME"="Intel(R) PRO/1000 GT Desktop Adapter"

[HKEY_LOCAL_MACHINE\SOFTWARE\INVENTORY\MACHINE\SOFTWARE]
"OS.Arch"="x86"

csv 输出示例

MACHINE_ID,WINDOWS,CPU_NAME,CPU_PROCESSOR,SYSPAGEFILE,DISPLAY_RES,MEMORY_TOTAL,MEMORY_AVAILABLE,RAM,SYSTEM_LOCALE,TIME_ZONE,INSTALL_DATE,  
    1a,Microsoft Windows XP [Version 5.1.2600],Intel[R] PRO/1000 GT Desktop Adapter,x86 Family 15 Model 6 Stepping 5 GenuineIntel ~3192 Mhz,1524MB,800x600, ,3362103296K, ,en-us;English [United States],[GMT] Greenwich Mean Time ,-,5/19/2011, 
    1b,Microsoft Windows XP [Version 5.1.2600],Intel[R] PRO/1000 GT Desktop Adapter,x86 Family 15 Model 6 Stepping 5 GenuineIntel ~3192 Mhz,1524MB,800x600, ,3580018688K, ,en-us;English [United States],[GMT] Greenwich Mean Time ,-,9/26/2013, 
    1c,Microsoft Windows XP [Version 5.1.2600],-,x86 Family 6 Model 23 Stepping 10 GenuineIntel ~2593 Mhz, , , ,372687298560K, ,en-us;English [United States],[GMT] Greenwich Mean Time ,19/08/2014, 

更新: Magoo 的解决方案在某些情况下适用于 txt 文件,包括提供的示例,但我的 reg 文件似乎是 ucs2 LE 或 utf16 编码,这很混乱,有些有可能导致问题的奇怪字符,如果他有一个完整的文件问题解决将是更容易但不是我的选择。对于我 posted.

的问题,我已将他的解决方案标记为正确

我确实设法拼凑了一个 python 3.4 解决方案,我将在下面 post 提供给任何愿意使用它的人。它有点粗糙,不处理重复的注册表键,但我只是一个初学者。

import csv, re, os
from fnmatch import fnmatch

current = os.getcwd()
datadir = current + '\data\'
r = {}
rows=[]

with open('headers.csv','r') as headread:
    head = csv.DictReader(headread,dialect='excel',delimiter=',')
    headers = head.fieldnames

with open('data.csv','w') as f:
    f_csv = csv.DictWriter(f, headers,extrasaction='ignore',lineterminator = '\n')
    f_csv.writeheader()

for path, subdirs, files in os.walk(datadir):
    for filename in files:
        parse = (os.path.join(path, filename))
        with open(parse,encoding='utf16') as f:
            for line in f:
                li=line.strip()
                if li.startswith("\""):
                    (heading, val) = line.split("\"=\"")
                    val=val[:-1]
                    r[heading.strip("\"")] = val.strip("\"")
                    rows=[r]
        with open('data.csv','a') as f:
            f_csv = csv.DictWriter(f, headers,extrasaction='ignore',lineterminator = '\n')
            f_csv.writerows(rows)

此脚本希望在 headers.csv 中包含 headers,并且相关文件位于同一目录的 'data' 文件夹中。我是初学者,所以可能不是最好的方法,但它对我有帮助。

@ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION 
:: delete output file
DEL "newfile.txt" >NUL 2>nul
:: remove variables starting $ or #
:: remove variables starting $
FOR  /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
CALL :zap#
:: Set column headers
SET /a columncount=0
FOR /f "tokens=1*delims==" %%a IN (q27905448.ct8) DO (
 SET /a columncount+=1
 SET "$!columncount!=%%a"
 SET "#!columncount!=%%a"
)
CALL :show
FOR %%f IN (q27905448.txt) DO (
 CALL :zap#
 SET "#1=%%~nf"
 FOR /f "tokens=1*delims==" %%a IN (%%f) DO (
  SET "name=%%~a"
  SET "value=%%~b"
  CALL :fit
 )
 CALL :show
)


GOTO :EOF

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

:show
SET "outline="
FOR /L %%x IN (1,1,%columncount%) DO (
 IF "!$%%x:~0,1!" neq "[" (
  SET "outline=!outline!,"!#%%x!""
 )
)
>>"newfile.txt" ECHO(%outline:~1%
GOTO :eof

:fit
IF "%name:~0,1%"=="[" GOTO newsection
IF %section% equ 0 GOTO :EOF 
FOR /L %%x IN (%section%,1,%columncount%) DO (
 IF /i "!$%%x!"=="%name%" FOR /f "tokens=*" %%y IN ("%value%") DO SET "#%%x=%%y"&GOTO :EOF 
 IF "!$%%x:~0,1!" equ "[" GOTO :eof
)
GOTO :eof

:: Locate sectionname index or 0 if section not being reported
:newsection
SET /a section=0
FOR /L %%x IN (1,1,%columncount%) DO (
 IF /i "!$%%x!"=="%name%" SET /a section=%%x+1&GOTO :EOF 
)
GOTO :eof

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

产生newfile.txt

你不说机器名是从哪里来的。我只是使用了源文件的名称。

使用文件定义所需的数据字段:

Machine_ID
[HKEY_LOCAL_MACHINE\SOFTWARE\INVENTORY\MACHINE]
WINDOWS
PROCESSOR
SYSPAGEFILE
Sausages
DISPLAY_RES
Candlepower
CPU_NAME

[HKEY_LOCAL_MACHINE\SOFTWARE\INVENTORY\MACHINE\SOFTWARE]
STRENGTH
OS.Arch

也就是说,[sectionname] fields-required as a list in q27905448.ct8(我添加了几个虚假字段来表示缺失值)。

第一个条目是特殊的-得到machine_ID。应用数据的方法在代码中-只需将#1设置为所需的值即可。

会有一个文件列表分配给 %%f - 不知道你到底想做什么,所以这可能来自文件或 dir/b 扫描。

从那里开始,只需使用 $n 中的模板将找到的值分配给 #n。根据您的输入文件,我的结果是

"Machine_ID","WINDOWS","PROCESSOR","SYSPAGEFILE","Sausages","DISPLAY_RES","Candlepower","CPU_NAME","STRENGTH","OS.Arch"
"q27905448","Microsoft Windows XP [Version 5.1.2600]","Intel(R) Celeron(R) D CPU 3.20GHz","1524MB","","800x600","","Intel(R) PRO/1000 GT Desktop Adapter","","x86"