使用grep和特殊字符提取文本

时间:2014-03-19 18:15:52

标签: r 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

然而,这可能是一个后续问题。

4 个答案:

答案 0 :(得分: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 :(得分:1)

这不是世界上最漂亮的东西,但您可以结合使用gsubgrepstrsplit来获得“理想”答案。

> 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

答案 2 :(得分: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      '

答案 3 :(得分: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