Groovy 解析文本文件 [英] Groovy parsing text file
问题描述
我有一个要解析的文件日志,但遇到了一些问题.起初,这似乎很简单.我会继续发布我想出的来源,然后解释我想要做什么.
I have a file log that I would like to parse and am having some issues. At first it seemed it would be simple. I'll go ahead and post the source I have come up with and then explain what I am trying to do.
我试图解析的文件包含以下数据:
The file I'm trying to parse contains this data:
HDD Device 0 : /dev/sda
HDD Model ID : ST3160815A
HDD Serial No : 5RA020QY
HDD Revision : 3.AAA
HDD Size : 152628 MB
Interface : IDE/ATA
Temperature : 33 C
Health : 100%
Performance : 70%
Power on Time : 27 days, 13 hours
Est. Lifetime : more than 1000 days
HDD Device 1 : /dev/sdb
HDD Model ID : TOSHIBA MK1237GSX
HDD Serial No : 97LVF9MHS
HDD Revision : DL130M
HDD Size : 114473 MB
Interface : S-ATA
Temperature : 30 C
Health : 100%
Performance : 100%
Power on Time : 38 days, 11 hours
Est. Lifetime : more than 1000 days
我的源代码(如下)基本上是将文件逐行拆分,然后将行拆分为两行(key:value).
My source code (below) basically breaks up the file line by line and then splits the line into two (key:value).
来源:
def dataList = [:]
def theInfoName = "C:\testdata.txt"
File theInfoFile = new File(theInfoName)
def words
def key
def value
if (!theInfoFile.exists()) {
println "File does not exist"
} else {
theInfoFile.eachLine { line ->
if (line.trim().size() == 0) {
return null
} else {
words = line.split(" : ")
key=words[0]
value=words[1]
dataList[key]=value
println "${words[0]}=${words[1]}"
}
}
println "$dataList.Performance" //test if Performance has over-written the previous Performance value
}
我的源代码的问题在于,当我使用 getter(例如 $dataList.Performance)时,它只显示文件中的最后一个而不是两个.
The problem with my source is that when I use my getters (such as $dataList.Performance) it only shows the last one in the file rather than two.
所以我想知道,我如何解析文件以保留两个硬盘驱动器的信息?有没有办法将信息打包到硬盘对象"中?
So I'm wondering, how do I parse the file so that it keeps the information for both hard drives? Is there a way to pack the info into a 'hard drive object'?
感谢任何和所有帮助
一些旁注:
该文件在 windows 机器上(即使信息是从 nix 系统中获取的)
The file is on a windows machine (even though the info is grabbed from a nix system)
文本文件由制表符、冒号和空格分隔(如我的源代码中所示),我只是想说明这一点,因为它在此页面上看起来不像.
The text file is split by a tab, colon, and space (like shown in my source code) just thought I would state that because it doesn't look like that on this page.
推荐答案
这将读取块中的数据(用空行分隔块)
This will read the data in blocks (with blank lines separating the blocks)
def dataList = []
def theInfoName = 'testdata.txt'
File theInfoFile = new File( theInfoName )
if( !theInfoFile.exists() ) {
println "File does not exist"
} else {
def driveInfo = [:]
// Step through each line in the file
theInfoFile.eachLine { line ->
// If the line isn't blank
if( line.trim() ) {
// Split into a key and value
def (key,value) = line.split( ' : ' ).collect { it.trim() }
// and store them in the driveInfo Map
driveInfo."$key" = value
}
else {
// If the line is blank, and we have some info
if( driveInfo ) {
// store it in the list
dataList << driveInfo
// and clear it
driveInfo = [:]
}
}
}
// when we've finished the file, store any remaining data
if( driveInfo ) {
dataList << driveInfo
}
}
dataList.eachWithIndex { it, index ->
println "Drive $index"
it.each { k, v ->
println " $k = $v"
}
}
手指交叉,您的硬盘信息部分之间有空行(您在测试数据中显示了一个):-)
Fingers crossed you have blank lines between your HDD info sections (you showed one in your test data) :-)
顺便说一句:我得到以下输出:
btw: I get the following output:
Drive 0
HDD Device 0 = /dev/sda
HDD Model ID = ST3160815A
HDD Serial No = 5RA020QY
HDD Revision = 3.AAA
HDD Size = 152628 MB
Interface = IDE/ATA
Temperature = 33 C
Health = 100%
Performance = 70%
Power on Time = 27 days, 13 hours
Est. Lifetime = more than 1000 days
Drive 1
HDD Device 1 = /dev/sdb
HDD Model ID = TOSHIBA MK1237GSX
HDD Serial No = 97LVF9MHS
HDD Revision = DL130M
HDD Size = 114473 MB
Interface = S-ATA
Temperature = 30 C
Health = 100%
Performance = 100%
Power on Time = 38 days, 11 hours
Est. Lifetime = more than 1000 days
<小时>
胡说八道,我也把代码归结为:
Messing around, I also got the code down to:
def dataList = []
def theInfoFile = new File( 'testdata.txt' )
if( !theInfoFile.exists() ) {
println "File does not exist"
} else {
// Split the text of the file into blocks separated by
// Then, starting with an empty list go through each block of text in turn
dataList = theInfoFile.text.split( '
' ).inject( [] ) { list, block ->
// Split the current block into lines (based on the newline char)
// Then starting with an empty map, go through each line in turn
// when done, add this map to the list we created in the line above
list << block.split( '
' ).inject( [:] ) { map, line ->
// Split the line up into a key and a value (trimming each element)
def (key,value) = line.split( ' : ' ).collect { it.trim() }
// Then, add this key:value mapping to the map we created 2 lines above
map << [ (key): value ] // The leftShift operator also returns the map
// the inject closure has to return the accumulated
// state each time the closure is called
}
}
}
dataList.eachWithIndex { it, index ->
println "Drive $index"
it.each { k, v ->
println " $k = $v"
}
}
但这必须一次将整个文件加载到内存中(并且依赖于
作为 EOL 终止符)
But that has to load the whole file into memory at once (and relies on
as the EOL termination char)
这篇关于Groovy 解析文本文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!