中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
作者:
标题: 求解难题-读取日志文件 上一主题 | 下一主题
pitt0303
新手上路





积分 6
发帖 6
注册 2010-1-25
状态 离线
『楼 主』:  求解难题-读取日志文件

我需要读取这个日志文件, 这个文件的格式是:

<startedTimestamp>2010-03-02T22:39:55+01:00</startedTimestamp>
  <event name="InstallationStarted">2010-03-02T22:39:55+01:00</event>
  <event name="IdleCheckPassed">2010-03-02T22:40:05+01:00</event>
  <event name="MonitorDeploymentStarted">2010-03-02T22:40:05+01:00</event>
  <event name="MonitorDeploymentCompleted">2010-03-02T22:41:20+01:00</event>
  <event name="CustomizationPointBeforeTheWholeUpgradeStarted">2010-03-02T22:41:20+01:00</event>
  <event name="CustomizationPointBeforeTheWholeUpgradeCompleted">2010-03-02T22:41:20+01:00</event>
  <event name="SanityChecksStarted">2010-03-02T22:41:20+01:00</event>
  <event name="InstallationFailed">2010-03-02T22:41:27+01:00</event>
  <errorMessage>Please attend to pending fuel price changes before attempting an upgrade.</errorMessage>
  <stackTrace>Radiant.RPOS.InstallRPOS.Exceptions.InstallationAttemptFailedException: Please attend to pending fuel price changes before attempting an upgrade.
   at Radiant.RPOS.InstallRPOS.Engine.ManifestInterpreter.ProcessBuiltinInstallationManifest()
   at Radiant.RPOS.InstallRPOS.Engine.InstallRPOS.Main()</stackTrace>
  <stoppedTimestamp>2010-03-02T22:41:27+01:00</stoppedTimestamp>

然后将这个日志读取并采用一个格式输出到文本里面,例如:

Example – parsing an <event> node
<event name="InstallationStarted">2010-03-02T22:39:55+01:00</event>
Parses to:
EventType = Event
EventDescription = InstallationStarted
EventTime = 2010-03-02T22:39:55+01:00

Example – parsing an <errorMessage> node
<errorMessage>Please attend to pending fuel price changes before attempting an upgrade.</errorMessage>
Parses to:
EventType = Error
EventDescription = Please attend to pending fuel price changes before attempting an upgrade.

Example – parsing a <startedTimestamp> node
<startedTimestamp>2010-03-02T22:39:55+01:00</startedTimestamp>
Parses to:
EventType = Started
EventTime = 2010-03-02T22:39:55+01:00

我原本是想逐行读取的,但现在按照这个要求是不行了. 希望标准的输入格式:

<Event><InstallationStarted><2010-03-02T22:39:55+01:00>
<Error><Please attend to pending fuel price changes before attempting an upgrade.>

这里不需要考虑<stackTrace>的信息,可以直接跳过不处理.

由于小弟几乎没接触过CMD的程序,而且这次任务又很急,所以想请大家帮忙.

谢谢

2010-4-7 04:24
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
Hanyeguxing
银牌会员

正在学习中的菜鸟...


积分 1039
发帖 897
注册 2009-3-1
来自 在地狱中仰望天堂
状态 离线
『第 2 楼』:  

具体说明描述你想做什么



批处理之家 http://bbs.bathome.net/forum-5-1.html
2010-4-7 11:44
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
pitt0303
新手上路





积分 6
发帖 6
注册 2010-1-25
状态 离线
『第 3 楼』:  

读取以下的日志文件,然后按规定的格式输出到新的文本。

这个是原始的日志文件样式:

<startedTimestamp>2010-03-02T22:39:55+01:00</startedTimestamp>
<event name="InstallationFailed">2010-03-02T22:41:27+01:00</event>
<errorMessage>Please attend to pending fuel price changes before attempting an upgrade.</errorMessage>
<stackTrace>Radiant.RPOS.InstallRPOS.Exceptions.InstallationAttemptFailedException: Please attend to pending fuel price changes before attempting an upgrade.
   at Radiant.RPOS.InstallRPOS.Engine.ManifestInterpreter.ProcessBuiltinInstallationManifest()
   at Radiant.RPOS.InstallRPOS.Engine.InstallRPOS.Main()</stackTrace>
<stoppedTimestamp>2010-03-02T22:41:27+01:00</stoppedTimestamp>

要求输入的文本格式要求有4个变量,一个是事件类型,一个是事件内容,还有时间,最后是bat读取这个日志最新信息的时间。

Example – parsing an <event> node
<event name="InstallationStarted">2010-03-02T22:39:55+01:00</event>
Parses to:
EventType = Event
EventDescription = InstallationStarted
EventTime = 2010-03-02T22:39:55+01:00

Example – parsing an <errorMessage> node
<errorMessage>Please attend to pending fuel price changes before attempting an upgrade.</errorMessage>
Parses to:
EventType = Error
EventDescription = Please attend to pending fuel price changes before attempting an upgrade.

Example – parsing a <startedTimestamp> node
<startedTimestamp>2010-03-02T22:39:55+01:00</startedTimestamp>
Parses to:
EventType = Started
EventTime = 2010-03-02T22:39:55+01:00


如果事件是stackTrace则不读取。

不知道说清楚了没有。

[ Last edited by pitt0303 on 2010-4-7 at 13:12 ]

2010-4-7 13:06
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
exzzz
初级用户

游手好闲 + 无所事事 ..



积分 194
发帖 167
注册 2007-4-30
状态 离线
『第 4 楼』:  

我觉得过滤可以用 findstr
/V是只显示不包含关键词的行,将其转向输出到某个文件就过滤掉那些信息了。

用for命令,用 / 做为分隔符,只读取前面的变量转向到一个文件,就去掉结尾句了
然后用<跟>作为分隔符,读取变量并一行行的转向到某个文件就OK了啊



  
2010-4-7 23:27
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
pitt0303
新手上路





积分 6
发帖 6
注册 2010-1-25
状态 离线
『第 5 楼』:  

那是不是会比较麻烦呢,因为日志文件里面的内容很多啊

[ Last edited by pitt0303 on 2010-4-8 at 01:04 ]

2010-4-8 00:53
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
exzzz
初级用户

游手好闲 + 无所事事 ..



积分 194
发帖 167
注册 2007-4-30
状态 离线
『第 6 楼』:  

我觉得不麻烦吧,也就3小段脚本就可以解决了,如果关闭显示,很快就处理完了。



  
2010-4-8 10:31
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
pitt0303
新手上路





积分 6
发帖 6
注册 2010-1-25
状态 离线
『第 7 楼』:  

能不能麻烦给我一个例子了,我对批处理不是很了解。先谢谢了。

2010-4-8 10:52
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
exzzz
初级用户

游手好闲 + 无所事事 ..



积分 194
发帖 167
注册 2007-4-30
状态 离线
『第 8 楼』:  


cls
setlocal enabledelayedexpansion
del /f numtodel1.txt
del /f numtodel2.txt
del /f linetodel.txt
del /f sam1.txt
del /f sam2.txt
del /f fileline.txt

:将sam.txt中的空行去掉,生成一个sam1.txt文件
for /f "delims=" %%a in (sam.txt) do echo %%a>>sam1.txt

:标记所有含有stackTrace事件的行号
findstr /i /n /c:stack sam1.txt>linetodel.txt
for /f "delims=:" %%a in (linetodel.txt) do echo %%a>>numtodel1.txt

:根据标记stack的行号X1,X2,X3,X4,生成X1到X2,X3到X4的行号
setlocal enabledelayedexpansion
set begin=
set now=
set end=
set begin=shit
for /f %%a in (numtodel1.txt) do (
        set now=%%a
        echo %%a !now!
        if #!begin!#==#shit# (
                set begin=!now!
                echo now begin=!begin!
        ) else (
                set end=!now!
                echo now begin=!begin! end=!end!
                for /l %%a in (!begin!,1,!end!) do echo #%%a#>>numtodel2.txt

                set begin=shit
        )
)

:得到sam1文件的行数
findstr /n /c:^> sam1.txt>filelines.txt
for /f "delims=:" %%a in (filelines.txt) do set maxline=%%a
echo 最大行数 %maxline%


:读取sam1.txt每一行,并且在numtodel2.txt中搜索该行的号码
:如果找到的,说明该行不需要读取,没有就转向输出到sam2.txt
set num=0
for /f "delims=" %%i in (sam1.txt) do (
set /a num+=1
set str=%%i
findstr /c:#!num!# numtodel2.txt>nul 2>nul
if !errorlevel! neq 0 echo !str!>>sam2.txt
if !num! gtr !maxline! goto end
)
)

:end

:至此文件中所有包含stack的段都去掉了

:去掉每行末尾的/之后的字符
for /f "delims=^/" %%a in (sam2.txt) do echo %%a >>sam3.txt


:暂时就写到这里了,剩下的用for /f处理吧




  
2010-4-8 12:59
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
Hanyeguxing
银牌会员

正在学习中的菜鸟...


积分 1039
发帖 897
注册 2009-3-1
来自 在地狱中仰望天堂
状态 离线
『第 9 楼』:  

源文件:a.log,输出文件:b.log,按照1楼的样式猜测你的意思。。。。
@echo off&setlocal enabledelayedexpansion
for /f "tokens=*" %%a in (a.log) do (
set a=%%a&set "a=!a:<=|!"&set "a=!a:>=|!"
if "!a:~0,1!"=="|" if not "!a:~1,10!"=="stackTrace" (
for /f "tokens=1-3 delims=|" %%b in ("!a!") do (
set b=%%b&set c=%%c&set d=%%d&echo.Example – parsing a ^<!d:~1!^> node
set c=%%c&set d="!d:~1!"&call:d !d!
echo.%%a&echo.Parses to:&echo.EventType = !d!
if "!b:~10,1!"=="=" echo.EventDescription = !b:~12,-1!
if "!c:~0,1!"=="2" (echo.EventTime = !c!) else echo.EventDescription = !c!
echo.)))>>b.log
pause&exit
:d
set d=%~1
:e
if not "!d:~%n%,1!"=="" set/a n+=1&goto e
set/a n=%n%-1
for %%i in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
for /l %%j in (0,1,%n%) do if "%%i"=="!d:~%%j,1!" set d=!d:~0,%%j!&goto :eof)




批处理之家 http://bbs.bathome.net/forum-5-1.html
2010-4-8 14:56
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
pitt0303
新手上路





积分 6
发帖 6
注册 2010-1-25
状态 离线
『第 10 楼』:  

谢谢大家的帮忙,问题已经解决,非常谢谢你们.

2010-4-9 23:25
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: