【问题标题】:How to extract data from a text file using R or PowerShell?如何使用 R 或 PowerShell 从文本文件中提取数据?
【发布时间】:2012-02-17 17:47:21
【问题描述】:

我有一个包含如下数据的文本文件:

This is just text
-------------------------------
Username:          SOMETHI           C:                 [Text]
Account:           DFAG              Finish time:        1-JAN-2011 00:31:58.91
Process ID:        2028aaB           Start time:        31-DEC-2010 20:27:15.30

This is just text
-------------------------------
Username:          SOMEGG            C:                 [Text]
Account:           DFAG              Finish time:        1-JAN-2011 00:31:58.91
Process ID:        20dd33DB          Start time:        12-DEC-2010 20:27:15.30

This is just text
-------------------------------
Username:          SOMEYY            C:                 [Text]
Account:           DFAG              Finish time:        1-JAN-2011 00:31:58.91
Process ID:        202223DB          Start time:        15-DEC-2010 20:27:15.30

有没有办法从这种数据中提取用户名、完成时间、开始时间?我正在寻找一些使用 R 或 Powershell 的起点。

【问题讨论】:

    标签: r powershell powershell-2.0 text-processing


    【解决方案1】:

    您的文件是否在数据框中?就像列名是用户名、进程 ID、开始时间...如果是这样,您可以通过

    轻松提取它
    df$Username (where df is your data frame and if you want to see all your usernames)
    df$FinishTime
    

    如果您想了解某个用户的所有信息,请使用此

    df[df$username == "SOMETHI",]
    

    如果你想知道一个有完成时间的用户..

    希望这可以作为一个起点。如果不清楚,请告诉我。

    【讨论】:

    • 我认为他正在尝试提取数据,以便将其放入 data.frame 中。
    【解决方案2】:

    这些只是我如何解决问题的指导方针。我敢肯定有一种更奇特的方式来做到这一点。可能包括 plyr。 :)

    rara <- readLines("test.txt") # you could use readLines(textConnection = "text"))
    
    # find usernames
    usn <- rara[grepl("Username:", rara)]
    # you can find a fancy way to split or weed out spaces
    # I crudely do it like this:
    unlist(lapply(strsplit(usn, "      "), "[", 2)) # 2 means "extract the second element"
    
    # and accounts
    acc <- rara[grepl("Account:", rara)]
    unlist(lapply(strsplit(acc, "      "), "[", 2))
    

    您可以使用str_trim() 删除单词之前/之后的空格。希望有足够的指示让您继续前进。

    【讨论】:

      【解决方案3】:

      R 可能不是处理文本文件的最佳工具,但您可以执行以下操作:通过将文件读取为固定宽度文件来识别两列,通过拆分冒号上的字符串将字段与其值分开,添加一个“id”列,然后将所有内容放回原处。

      # Read the file
      d <- read.fwf("A.txt", c(37,100), stringsAsFactors=FALSE)
      
      # Separate fields and values
      d <- d[grep(":", d$V1),]
      d <- cbind( 
        do.call( rbind, strsplit(d$V1, ":\\s+") ), 
        do.call( rbind, strsplit(d$V2, ":\\s+") ) 
      )
      
      # Add an id column
      d <- cbind( d, cumsum( d[,1] == "Username" ) )
      
      # Stack the left and right parts
      d <- rbind( d[,c(5,1,2)], d[,c(5,3,4)] )
      colnames(d) <- c("id", "field", "value")
      d <- as.data.frame(d)
      d$value <- gsub("\\s+$", "", d$value)
      
      # Convert to a wide data.frame
      library(reshape2)
      d <- dcast( d, id ~ field )
      

      【讨论】:

      • 处理文本文件的工具是什么? Perl,也许是 Ruby?
      • @RomanLuštrik:我个人会使用 Perl,因为我很熟悉它,但 Python 或 Ruby 应该证明同样好的解决方案。我通常更喜欢单独进行所有预处理,这样 R 只需读取数据库中的 csv 文件或表。
      • R 在解析文本文件时速度非常慢,用 Perl 或 Python 代替。
      【解决方案4】:

      这是一个 Powershell 解决方案:

      $result = @()
      
      get-content c:\somedir\somefile.txt |
      foreach {
          if ($_ -match '^Username:\s+(\S+)'){
              $rec = ""|select UserName,FinishTime,StartTime
              $rec.UserName = $matches[1]
              }
          elseif ($_ -match '^Account.+Finish\stime:\s+(.+)'){
              $rec.FinishTime = $matches[1]
              }
          elseif ($_ -match '^Process\sID:\s+\S+\s+Start\stime:\s+(.+)'){
              $rec.StartTime = $matches[1]
              $result += $rec
              }
      }
      $result
      

      【讨论】:

        猜你喜欢
        • 2011-01-30
        • 1970-01-01
        • 1970-01-01
        • 2018-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多