我正在尝试从文本文件中提取特定行。我通常使用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
然而,这可能是一个后续问题。
答案 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)
这不是世界上最漂亮的东西,但您可以结合使用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
答案 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