2012-01-24 6 views
6

Mam plik tekstowy zawierający dane tak:Jak wyodrębnić dane z pliku tekstowego za pomocą R lub 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 

Czy istnieje sposób, aby wyodrębnić czasu Nazwa użytkownika, wykończenie, czas rozpoczęcia z tego rodzaju danych? Szukam jakiegoś punktu początkowego us R lub Powershell.

Odpowiedz

8

R może nie być najlepszym narzędziem do przetwarzania plików tekstowych, ale możesz postępować w następujący sposób: zidentyfikuj dwie kolumny, odczytując plik jako plik o stałej szerokości, oddzielając pola od ich wartości, dzieląc łańcuchy na dwukropki, dodaj kolumnę "id" i uporządkuj wszystko.

# 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

Dzięki, działa jak urok! – jrara

+0

Jakie byłoby Twoje narzędzie do pracy z plikami tekstowymi? Perl, może Ruby? –

+1

@ RomanLuštrik: Osobiście użyłbym Perla, ponieważ dobrze go znam, ale Python lub Ruby powinny okazać równie dobre rozwiązania. Zazwyczaj wolę wykonywać wszystkie preprocessing osobno, tak aby R tylko musiał odczytać pliki csv lub tabele w bazie danych. –

0

Czy masz plik w ramce danych? Jak nazwy kolumn byłoby Nazwa użytkownika, identyfikator procesu, czas rozpoczęcia ... Jeśli tak, można w łatwy wyodrębnić go

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

Jeśli chcesz dowiedzieć się wszystkiego na temat użytkownika z określoną nazwą, należy użyć tego

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

Jeśli chcesz dowiedzieć się użytkownikowi czas mety ..

Nadzieja ta może być punktem wyjścia. Daj mi znać, jeśli coś nie jest jasne.

+0

Myślę, że próbuje wydobyć dane, aby mógł umieścić go w data.frame. –

2

To tylko wskazówki, jak podejść do problemu. Jestem pewien, że jest na to bardziej wymyślny sposób. Prawdopodobnie w tym 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)) 

Można użyć str_trim() usunąć spacje przed/po słowie. Mam nadzieję, że jest wystarczająco dużo wskazówek, abyś mógł iść.

2

Oto rozwiązanie 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