2014-03-19 5 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)] 

Как я могу получить общий подход к работе? Я не думаю, что - и + требуют escape-символа, но я могу ошибаться. Спасибо за любой совет.

EDIT

В идеале я хотел бы извлечь:

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 или больше, так что в исходном выражении -+, скорее всего, интерпретируется как один или более - с вместо того, что вы имели в виду.

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, grep и strsplit, чтобы получить ваш «идеальный» ответ.

> 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 
Смежные вопросы