我有一个日志文件,我们称之为mylogfile.txt
格式是 日期 - 时间戳,然后是分号分隔符,然后是我为此练习的目的而不关心的其他一些东西。
例如(这是日志文件中的所有一行 - 不确定如何在SO中表达如此道歉)
20170710-23:59:43.158;B@13.43434@1000000.0@20170710-21:15:53.23@@2017071023:59:43.158@@T@20170710-23:59:43.156#B@13.41834@4000000.0@20170710-21:15:53.23@@20170710-23:59:43.158@@T@20170710-23:59:43.156#A@13.47274@1000000.0@20170710-21:15:53.23@@20170710-23:59:43.158@@T@20170710-23:59:43.156#A@13.48874@4000000.0@20170710-21:15:53.23@@20170710-23:59:43.158@@T@20170710-23:59:43.156#
我目前正在尝试的只是一个概念验证示例。我希望解析文件,反转行顺序,并在输出中返回两列 -
1)只是从第一列解析的时间戳(这是一种日期 - 时间格式,所以我需要丢弃日期部分)
2)自午夜以秒为单位表示的时间戳,以毫秒精度表示(与时间戳本身的粒度一致。
所以从下面的单行示例中输出将是例如
23:59:43.158,86383.158
我可以半途而废。我可以使用语法来构造对awk的调用,该语法在cygwin中完美地运行(自然地剥离了R包装器)。但它在R
中不起作用testawk<-paste0("tac ", mylogfile.txt, " | awk 'BEGIN {FS=\"-|;|:\"} {OMFT=\"%.3f\"} {print $2 \":\" $3 \":\" $4 \",\" (3600*$2)+(60*$3)+$4}' ")
getawk<-as.data.frame(system(testawk, intern=TRUE, show.output.on.console = FALSE))
然而,在数据框架getawk中结束的只是原始日志文件在正在读取时翻译。另外,我收到警告消息,即运行命令的状态为1。
无论其
如果我脱掉'tac'片而只是使用直awk,因此;
testawk<-paste0("awk 'BEGIN {FS=\"-|;|:\"} {OMFT=\"%.3f\"} {print $2 \":\" $3 \":\" $4 \",\" (3600*$2)+(60*$3)+$4}' ", mylogfile.txt)
getawk<-as.data.frame(system(testawk, intern=TRUE, show.output.on.console = FALSE))
我收到错误消息
Error in system(testawk, intern = TRUE, show.output.on.console = FALSE) :
'awk' not found
我不认为问题出在我的awk构造中,因为如果我只是在cygwin中执行它,它可以正常工作。所以很明显r / system / awk交互的一些方面我还没有完全掌握。
我想如果我把它全部包装在一个awk脚本中并简单地调用它可能有效,但我很沮丧我不能简单地找到正确的语法来直接用R系统命令调用awk(我处理grep,sed命令等等,好吧)。
它不像awk那样简单,实际上根本不受支持吗?
指针非常感谢。如果第一个说日志文件的20行是有用的,我也可以发布它们。
答案 0 :(得分:1)
当尝试使用其他语言时,通常会发生这种情况,例如:蟒蛇。如果您还没有添加到Windows系统路径的路径,那么您还没有告诉RStudio在哪里可以找到可执行文件。
Cygwin的根通常位于C:\cygwin64
(但可能因安装而异),因此找到安装并查找bin
文件夹。应该有awk可执行文件,但它通常只是gawk
可执行文件的符号链接(自己验证),所以将它添加到PATH中,例如:
Sys.setenv(PATH = paste("C:/cygwin64/bin/gawk", Sys.getenv("PATH"), sep = ":"))
注意:这不会永久添加,因此您必须从每个会话开始时开始,或add to your Windows path以永久识别它。
答案 1 :(得分:1)
听起来像是&#39; awk&#39;根本找不到,也许它不在你的路径中。尝试放入awk的完整路径,例如&#39;在/ usr /斌/ AWK&#39 ;.我没有使用Windows和Cygwin,所以你真正的道路肯定会有所不同。
答案 2 :(得分:0)
只需在R中完成所有操作:
c(
"20170710-10:31:26.121;B@13.43434@1000000.0@20170710-21:15:53.23@@2017071023:59:43.158@@T@20170710-23:59:43.156#B@13.41834@4000000.0@20170710-21:15:53.23@@20170710-23:59:43.158@@T@20170710-23:59:43.156#A@13.47274@1000000.0@20170710-21:15:53.23@@20170710-23:59:43.158@@T@20170710-23:59:43.156#A@13.48874@4000000.0@20170710-21:15:53.23@@20170710-23:59:43.158@@T@20170710-23:59:43.156#",
"20170710-23:59:43.158;B@13.43434@1000000.0@20170710-21:15:53.23@@2017071023:59:43.158@@T@20170710-23:59:43.156#B@13.41834@4000000.0@20170710-21:15:53.23@@20170710-23:59:43.158@@T@20170710-23:59:43.156#A@13.47274@1000000.0@20170710-21:15:53.23@@20170710-23:59:43.158@@T@20170710-23:59:43.156#A@13.48874@4000000.0@20170710-21:15:53.23@@20170710-23:59:43.158@@T@20170710-23:59:43.156#"
) -> log_lines
# you'd get the above with `log_lines <- readLines('filename')`
matched <- stringi::stri_match_first_regex(log_lines, "([[:digit:]]+:[[:digit:]]+:[[:digit:]]+\\.[[:digit:]]+)")[,2]
cat(
rev(
sprintf(
"%s,%s\n",
matched,
lubridate::hms(matched) %>%
as.numeric() %>%
sprintf("%9.3f", .)
)
),
sep=""
)
这样做:
10:31:26.121,37886.121
23:59:43.158,86383.158
并且,您可以cat
到文件或存储在数据框(等)中。
我认为awk
对你来说可能比较熟悉,但使用它绝对没有意义。