Подтвердить что ты не робот

Как писать в буфер обмена на Ubuntu/Linux в R?

Я запускаю Ubuntu 11.10, и я хотел бы иметь возможность писать в буфер обмена (или первичный выбор). Ниже приведена ошибка

> x <- 1:10
> dput(x, 'clipboard')
Error in file(file, "wt") : 'mode' for the clipboard must be 'r' on Unix

Как я могу писать в буфер обмена/первичный выбор?

Обратите внимание, что я видел эту старую статью R-Help, но я все еще не понимаю, что я должен делать.

Linux не имеет буфер обмена, но сеанс X11 имеет вторичный выбор.? файл говорит

Clipboard

  'file' can also be used with 'description = "clipboard"' in mode
  '"r"' only.  It reads the X11 primary selection, which can also be
  specified as '"X11_primary"' and the secondary selection as
  '"X11_secondary"'.

  When the clipboard is opened for reading, the contents are
  immediately copied to internal storage in the connection.

  Unix users wishing to _write_ to the primary selection may be able
  to do so via 'xclip' (<URL:
  http://people.debian.org/~kims/xclip/>), for example by
  'pipe("xclip -i", "w")'.

поэтому RTFM. Запись на выбор X11 требует нескольких потоков и я не думал, что это стоит очень больших усилий (в отличие от Windows).

Обратите внимание, что диспетчеры окон могут иметь другие буфер обмена и, например, пакет RGtk2 имеет интерфейсы для буферов gtk.

4b9b3361

Ответ 1

Не уверен, что это лучший способ, но вот как я могу заставить его работать:

  • Установить xclip: sudo apt-get install xclip
  • Прочтите руководство: man xclip
  • Пишите на X11 primary в R: write.table(1:10, pipe("xclip -i", "w"))

Update:

Обратите внимание, что объект, переданный в write.table, не будет присутствовать в буфере обмена, пока труба не будет закрыта. Вы можете заставить трубку закрыть, вызвав gc(). Например:

write.table(1:10, pipe("xclip -i", "w"))  # data may not be in clipboard
gc()                                      # data written to primary clipboard

Лучшим способом управления соединением является использование функции с on.exit(close(con)), которая закроет канал, даже если вызов write.table вызывает ошибку. Обратите внимание, что вам нужно убедиться, что вы пишете в буфер обмена, который вы собираетесь использовать (основной по умолчанию), на основе вашей настройки системы.

write.xclip <- function(x, selection=c("primary", "secondary", "clipboard"), ...) {
  if (!isTRUE(file.exists(Sys.which("xclip")[1L])))
    stop("Cannot find xclip")
  selection <- match.arg(selection)[1L]
  con <- pipe(paste0("xclip -i -selection ", selection), "w")
  on.exit(close(con))
  write.table(x, con, ...)
}

Ответ 2

clipboard <- function(x, sep="\t", row.names=FALSE, col.names=TRUE){
     con <- pipe("xclip -selection clipboard -i", open="w")
     write.table(x, con, sep=sep, row.names=row.names, col.names=col.names)
     close(con)
}

vec <- c(1,2,3,4)

clipboard(vec)
clipboard(vec, ",", col.names=FALSE)
clipboard(vec, " ", row.names=TRUE)

Вы можете вставить все, что вы пишете в буфер обмена, после создания функции как таковой. По умолчанию возвращается вкладка разделенных значений со столбцом, но без имен строк. Укажите другие разделители, включите имена строк или исключите имена столбцов по своему вкусу, как показано.

Изменить: Чтобы уточнить, вам все равно нужно установить xclip. Однако вам не нужно начинать его по-отдельности сначала.

Ответ 3

Версии:

  • Монетный двор 18.1, Корица
  • xclip 0.12
  • R 3.4.0 (2017-04-21)

Я не мог заставить другие решения работать, поэтому я man разобрался. Этот подход работает для меня (на основе других решений).

write_clipboard = function(x, .rownames = F) {
    #decide how to write
    #windows is easy!
    if (Sys.info()['sysname'] %in% c("Windows")) {
      #just write as normal
      write.table(x, "clipboard", sep = "\t", na = "", row.names = F)
    } else {
      #for non-windows, try xclip approach
      #https://stackoverflow.com/a/10960498/3980197
      write.xclip = function(x) {
        #if xclip not installed
        if (!isTRUE(file.exists(Sys.which("xclip")[1L]))) {
          stop("Cannot find xclip")
        }
        con <- pipe("xclip -selection c", "w")
        on.exit(close(con))
        write.table(x, con, sep = "\t", na = "", row.names = F)
      }

      tryCatch({
        write.xclip(x)
      }, error = function(e) {
        message("Could not write using xclip")
      })
    }
}

Это орошенная версия функции в мой личный пакет R.

Чтение из буфера обмена

Чтение одинаково сложно. Здесь приведена вспомогательная функция для указанного выше.

read_clipboard = function(header = T,
                          sep = "\t",
                          na.strings = c("", "NA"),
                          check.names = T,
                          stringsAsFactors = F,
                          dec = ".",
                          ...) {
  #decide how to read
  #windows is easy!
  if (Sys.info()['sysname'] %in% c("Windows")) {
    #just read as normal
    read.table(file = con, sep = sep, header = header, check.names = check.names, na.strings = na.strings, stringsAsFactors = stringsAsFactors, dec = dec, ...)
  } else {
    #for non-windows, try xclip approach
    #https://stackoverflow.com/a/10960498/3980197
    read.xclip = function(x) {
      #if xclip not installed
      if (!isTRUE(file.exists(Sys.which("xclip")[1L]))) {
        stop("Cannot find xclip")
      }
      con <- pipe("xclip -o -selection c", "r")
      on.exit(close(con))
      read.table(file = con, sep = sep, header = header, check.names = check.names, na.strings = na.strings, stringsAsFactors = stringsAsFactors, dec = dec, ...)
    }

    tryCatch({
      read.xclip(x)
    }, error = function(e) {
      message(sprintf("error: %s", e$message))
    })
  }
}