【问题标题】:R system call to awk failR系统调用awk失败
【发布时间】:2017-08-01 12:31:22
【问题描述】:

我有一个日志文件,我们称之为 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

我可以走到一半。我可以使用在 cygwin 中运行良好的语法构造对 awk 的调用(自然地剥离了 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 行有用,我也可以发布。

【问题讨论】:

  • 你为什么要使用awk?您可以在 R 中轻松做到这一点。

标签: r bash awk


【解决方案1】:

当尝试将其他语言与 R 一起使用时,通常会发生这种情况,例如Python。如果您还没有将路径添加到 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 才能永久识别它。

【讨论】:

  • /usr/bin/awk 已返回。我会补充一点。谢谢(也感谢下面的海报)。
  • 很遗憾没用。仍然出现 awk not found 错误。当我在 windows 盒子上运行所有这些时,我需要一个更“windowey”的文件路径吗?
  • 好的,谢谢。原来它在 c:/installs/cygwin64/bin/awk 中,所以我尝试使用它运行命令。仍然没有喜悦。尝试重启 RStudio。
  • 你用了大写的C吗?您还需要在每次重新启动 RStudio 时运行该命令,因为这不会永久添加到 PATH
  • 嗯,好的。从另一个角度来看成功。我查看了 awk 可执行文件,它似乎只是一个 gawk 的链接。所以我尝试使用 gawk 调用 R 命令,这似乎工作正常。就每次都需要运行命令而言,我想我可以很容易地将它添加到我的启动脚本中,这是我日常工作的一部分。非常感谢您的帮助。终于到了。
【解决方案2】:

听起来像是根本找不到“awk”,也许它不在您的路径中。尝试输入 awk 的完整路径,例如'/usr/bin/awk'。我没有使用Windows和Cygwin,所以你的真实路径肯定会有所不同。

【讨论】:

    【解决方案3】:

    只需在 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 对你来说可能更熟悉,但使用它绝对没有意义。

    【讨论】:

    • 谢谢。我确实知道如何在 R 中做这些事情,但问题是具体如何调用 awk。正如我之前所说,那个特定的例子就是这样。一个例子。我还有其他用例。
    猜你喜欢
    • 2015-02-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2018-01-29
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 2013-10-02
    相关资源
    最近更新 更多