Groovy 解析文本文件 [英] Groovy parsing text file

查看:23
本文介绍了Groovy 解析文本文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个要解析的文件日志,但遇到了一些问题.起初,这似乎很简单.我会继续发布我想出的来源,然后解释我想要做什么.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆