Как писать в буфер обмена на 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.
Ответы
Ответ 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))
})
}
}