2014-03-19 61 views
0

我正在嘗試從文本文件中提取特定的行。我通常用grep來做到這一點。但是,我遇到了一種我通常的方法無效的情況。文本的例子塊是:用grep和特殊字符提取文本

my.text <- 'junk 1 
junk 2 
junk 3 
    | a   b   c   d   e   f  
----+------------------------------------------------------------------------ 
    | 
    1 | 1  2 3 4 5 6 
    | 6  5 4 3 2 1  ' 

my.data <- readLines(textConnection(my.text)) 

我想提取:

1 | 1  2 3 4 5 6 
    | 6  5 4 3 2 1 

下面的代碼工作,但不是一般的文件中:

b.top <- 'junk 3' 
my.data <- my.data[(grep(b.top, my.data)+4):length(my.data)] 

下面的代碼會一般在文件中,但不起作用:

b.top <- ' ----+------------------------------------------------------------------------' 
my.data <- my.data[(grep(b.top, my.data)+2):length(my.data)] 

我如何獲得一般工作方法?我不認爲-+需要轉義字符,但我可能是錯的。感謝您的任何建議。

編輯

理想我想提取:

1  2 3 4 5 6 
6  5 4 3 2 1 

然而,這可能是一個後續問題。

回答

1

在你原來的代碼,你只需要一個雙反斜線\\逃脫+

> b.top <- ' ----+------------------------------------------------------------------------' 
> grep(b.top, my.data) 
integer(0) 
> b.top <- ' ----\\+------------------------------------------------------------------------' 
> grep(b.top, my.data) 
[1] 5 
> my.data[(grep(b.top, my.data)+2):length(my.data)] 
[1] " 1 | 1  2 3 4 5 6 " "  | 6  5 4 3 2 1  " 
> 

+是一個限定詞,這意味着1以上,所以在原始表達式-+是最有可能的解釋爲一個或多個- s,而不是你的意思。

0

如果你喜歡線總在經過兩線,這可能awk工作:

awk -F\| '/----/ {f=NR} f && (NR==f+2 || NR==f+3) {print $2}' file 
    1  2 3 4 5 6 
    6  5 4 3 2 1  ' 
+0

謝謝。這看起來不像熟悉的'R'代碼,但我可以嘗試。 –

+0

我不確定你可以在'R'中使用它。如果沒有抱歉... – Jotne

0

這似乎工作:

my.text <- 'junk 1 
junk 2 
junk 3 
    | a   b   c   d   e   f  
----+------------------------------------------------------------------------ 
    | 
    1 | 1  2 3 4 5 6 
    | 6  5 4 3 2 1  ' 

my.data <- readLines(textConnection(my.text)) 

my.data <- my.data[(which(grepl("----", my.data)==TRUE)+2):length(my.data)] 
my.data 

[1] " 1 | 1  2 3 4 5 6 " "  | 6  5 4 3 2 1  " 

這裏是代碼轉換到理想的結果:

my.data2 <- substr(my.data, 7, nchar(my.data)) 
my.data2 

my.data3 <- read.table(text = my.data2, stringsAsFactors=FALSE, header = FALSE, strip.white=TRUE) 
my.data3 

    V1 V2 V3 V4 V5 V6 
1 1 2 3 4 5 6 
2 6 5 4 3 2 1 
1

不是在世界上最漂亮的事情,但你可以使用的gsub組合, grepstrsplit以獲得您的「理想」答案。

> g1 <- grep("[0-9]()", my.data, value = TRUE) 
> g2 <- gsub("(.*\\|[[:space:]]+)|([[:space:]]+) ", "", g1) 
> lapply(strsplit(g2, ""), as.numeric) 
## [[1]] 
## [1] 1 2 3 4 5 6 

## [[2]] 
## [1] 6 5 4 3 2 1