Search code examples
rfull-text-search

how to search for a string in an R code thought different files format, including .Rmd


How can I adjust this function to search into .R but also into .Rmd files and also looking into commented parts, e.g. #### ?

UFif <- function(what, where=".", in_files="\\.[Rr]$", recursive = TRUE, ignore.case = TRUE) {
  suppressWarnings({
  fils <- list.files(path = where, pattern = in_files, recursive = recursive)
  found <- FALSE
  file_cmd <- Sys.which("file")
  for (fil in fils) {
    if (nchar(file_cmd) > 0) {
      ftype <- system2(file_cmd, fil, TRUE)
      if (!grepl("text", ftype)[1]) next
    }
    contents <- readLines(fil)
    res <- grepl(what, contents, ignore.case = ignore.case)
    res <- which(res)
    if (length(res) > 0) {
      found <-  TRUE
      cat(sprintf("%s\n", fil), sep="")
      cat(sprintf(" % 4s: %s\n", res, contents[res]), sep="")
    }
  }
  if (!found) message("(No results found)")
  })
}

Solution

  • This version looks at .R and .Rmd files, plus can be limited to only checking commented lines:

    UFifv2 <- function(what, where=".", in_files="\\.(R|r|Rmd|rmd)$", 
                        recursive = FALSE, ignore.case = TRUE, comments.only=FALSE) {
      suppressWarnings({
      fils <- list.files(path = where, pattern = in_files, recursive = recursive)
      print(fils)
      cat("\n Searching...\n")
      found <- FALSE
      file_cmd <- Sys.which("file")
      for (fil in fils) {
        if (nchar(file_cmd) > 0) {
          ftype <- system2(file_cmd, fil, TRUE)
          if (!grepl("text", ftype)[1]) next
        }
        
        if(comments.only == FALSE) {
          contents <- readLines(fil)
          res <- grepl(what, contents, ignore.case = ignore.case)
          res <- which(res)
          if (length(res) > 0) {
            found <-  TRUE
            cat(sprintf("%s\n", fil), sep="")
            cat(sprintf(" % 4s: %s\n", res, contents[res]), sep="")
          }}
        if(comments.only == TRUE) {
          contents <- readLines(fil)
          contents <- contents[grepl('^#', contents)]
          res <- grepl(what, contents, ignore.case = ignore.case)
          res <- which(res)
          if (length(res) > 0) {
            found <-  TRUE
            cat(sprintf("%s\n", fil), sep="")
            cat(sprintf(" % 4s: %s\n", res, contents[res]), sep="")  
          }}
      }
      if (!found) message("(No results found)")
      })
    }
    
    
    UFifv2("dplyr")
    UFifv2("dplyr", comments.only=TRUE)