2012-01-24 19 views
6

Ho un file di testo contenente i dati in questo modo:Come estrarre i dati da un file di testo usando R o PowerShell?

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 

C'è un modo per estrarre il tempo Nome utente, Fine, ora di inizio da questo tipo di dati? Sto cercando un punto di partenza usign R o Powershell.

risposta

8

R potrebbe non essere lo strumento migliore per elaborare i file di testo, ma è possibile procedere come segue: identificare le due colonne leggendo il file come file a larghezza fissa, separare i campi dal loro valore dividendo le stringhe sul due punti, aggiungi una colonna "id" e rimetti tutto in ordine.

# 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) 
+0

Grazie, funziona come un incantesimo! – jrara

+0

Quale sarebbe il tuo strumento per lavorare con i file di testo? Perl, forse Ruby? –

+1

@ RomanLuštrik: Personalmente userò Perl, perché mi è familiare, ma Python o Ruby dovrebbero dimostrare soluzioni altrettanto valide. Solitamente preferisco eseguire tutte le operazioni di pre-elaborazione separatamente, in modo che R debba solo leggere file CSV o tabelle in un database. –

0

Avete il vostro file in un frame di dati? Come i nomi delle colonne sarebbero Nome utente, ID di processo, Ora di inizio ... Se è così, si può facilmente estrarre da

df$Username (where df is your data frame and if you want to see all your usernames) 
df$FinishTime 

Se volete sapere tutto di un utente con un certo nome, utilizzare questo

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

Se vuoi sapere un utente con un tempo finale ..

Spero che questo può essere un punto di partenza. Fammi sapere se sth non è chiaro.

+0

Penso che stia cercando di estrarre i dati in modo che possa metterlo in un data.frame. –

2

Queste sono solo le linee guida su come affrontare il problema. Sono sicuro che c'è un modo più elegante di farlo. Forse includendo 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)) 

È possibile utilizzare str_trim() per rimuovere gli spazi prima/dopo la parola. Spero ci siano abbastanza indicazioni per farti andare.

2

Ecco una soluzione 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 
Problemi correlati