将多个注册表转储批量解析为 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"
我需要使用注册表转储创建一个 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"