如何只附加到剪贴板(但不覆盖当前数据)?

我有一个相当大的文件,我需要在某处复制整个内容,但是当我向下滚动页面时,我选择的所有数据都将被取消选中。 我可以一块一块地复制和粘贴,但是我会发现它很容易,因为有很多数据,只是能够将内容附加到当前剪贴板数据的末尾。 那可能吗?

这样我就可以使用键盘快捷键来将其复制到剪贴板:

I am some nice new text. 

当这是已经存在的:

 I am the old text. 

粘贴时看起来像这样:

 I am the old text. I am some nice new text. 

所以我真的很喜欢这三件事(我会有3个单独的键盘快捷键来做到这一点):

  1. 将数据附加到剪贴板的末尾并将其放在RETURN之前(如上例所示)。

  2. 将数据附加到剪贴板的末尾但是要使它在它之前没有RETURN ,以便它最初在同一行上继续。

  3. 拥有所有这些,但是数据被放在剪贴板的开头,然后是当前存在的所有数据。

我正在使用GNOME 3.20运行Ubuntu GNOME 16.04。

这很简单,但您需要先安装xsel工具:

 sudo apt-get install xsel 

TL; DR:以下是您最终可能想要用于快捷方式的命令。 我正在使用printf的版本,以实现一致性和更容易的自定义,即使更简单的变体就足够了:

  • 将选择直接附加到剪贴板结尾:

     bash -c 'printf "%b%b" "$(xsel -b)" "$(xsel)" | xsel -ib ; xsel -c' 
  • 换行后将选择附加到剪贴板的末尾:

     bash -c 'printf "%b\n%b" "$(xsel -b)" "$(xsel)" | xsel -ib ; xsel -c' 
  • 将选择直接附加到剪贴板的开头:

     bash -c 'printf "%b%b" "$(xsel)" "$(xsel -b)" | xsel -ib ; xsel -c' 
  • 换行后将选择附加到剪贴板的开头:

     bash -c 'printf "%b\n%b" "$(xsel)" "$(xsel -b)" | xsel -ib ; xsel -c' 

在附加到剪贴板后,它们都包括主缓冲区重置,以防止双重附加相同的内容。 如果你不想那样,删除; xsel -c ; xsel -c从每个命令的末尾开始。


很长的解释:

您必须知道X包含3个缓冲区, 主要选择, 辅助选择和剪贴板

你知道剪贴板来自Ctrl + CCtrl + V等。它是你通常用来复制和粘贴东西的缓冲区。

主要选择是缓冲区,它总是自动包含您选择的文本,无论它在哪个窗口,并且没有任何其他用户交互。
我们只有一个问题:缓冲区在您选择文本片段时会更新,但是当您单击其他任何位置取消选择时,缓冲区不会被清除。 它仍将包含您上次选择的内容。

次要选择仅供少数程序使用,对我们来说不是很有趣。


这意味着我们可以使用下面的命令模仿Ctrl + C的行为,将主要选择(最后突出显示的文本)复制到剪贴板:

 xsel | xsel -ib 

没有任何参数的xsel将主要选择的内容打印到STDOUT。 xsel -ab将( -i )数据从STDIN写入剪贴板( -b )。


要直接将数据附加到当前剪贴板内容(中间没有换行符)而不是替换它,我们使用-a选项而不是-i 。 此命令会将最后选定的文本片段附加到当前剪贴板内容:

 xsel | xsel -ab 

如果您真的想要额外的换行符或任何其他格式,我们可以通过printf或您要用来处理它的任何其他工具来管道数据。 这是一个示例,它读取最后一个选择和当前剪贴板内容,并使用换行符将它们连接在一起:

 printf "%b\n%b" "$(xsel -b)" "$(xsel)" | xsel -ib 

xsel -b返回当前剪贴板内容。 printf的格式字符串使用%b作为参数的占位符, \n表示换行符。 您可以通过输入man printf找到有关printf的更多信息。

通过在字符串末尾切换两个参数,您可以反转它们的顺序并附加到开头而不是结尾。


如果您想避免意外地将相同的数据两次附加到剪贴板(如果要将它追加两次,则必须再次选择它!),您可以在使用此命令执行后手动清除主选择缓冲区:

 xsel -c 

只需在基本剪贴板附加命令之后运行它,如下所示:

 printf "%b\n%b" "$(xsel -b)" "$(xsel)" | xsel -ib ; xsel -c 

所以知道这一切,你可以为键盘快捷键编写完全符合你想要的命令,但请记住我们的单行程序都大量使用Bashfunction,比如管道,所以你需要用Bash运行它们:

 bash -c 'COMMAND' 

有关创建快捷方式的命令列表,请参阅答案顶部的TL; DR部分。

X服务器有多个剪贴板。 使用Ctrl + C的那个被称为剪贴板,突出显示某个内容的那个称为主要的。 xclip允许粘贴其中任何一个的输出。 例如,我复制了你问题的一部分,但突出显示了终端中的其他一些文字:

在此处输入图像描述

您可以在连接到键盘快捷键的脚本中进一步使用该想法。 事实上,我写了一个脚本,发布为github gist

基本思想是将其绑定到键盘快捷键。 突出显示要添加的内容,然后按快捷键。 例如,我将我的操作绑定到Ctrl + Alt + V. 确切的命令是python /path/to/file.py

用法示例:

  1. 突出显示I have a rather large file的post中I have a rather large file部分,并使用Ctrl + C进行复制
  2. 突出显示其他内容,例如That is so that I can have a keyboard shortcut
  3. 按快捷键(我的是Ctrl + Alt + V
  4. 使用Ctrl + V在某处释放附加的剪贴板。 结果输出是: I have a rather large fileThat is so that I can have a keyboard shortcut

脚本来源

  import gi gi.require_version('Notify', '0.7') from gi.repository import Notify import subprocess import os import sys # This script is meant to be bound to keyboard shortcut def send_notification(title, text): Notify.init(sys.argv[0]) n = Notify.Notification.new(title, text) n.show() def run_cmd(cmdlist): # function for running try: stdout = subprocess.check_output(cmdlist) except subprocess.CalledProcessError: send_notification(sys.argv[0],"Clipboard error") sys.exit(1) else: if stdout: return stdout # get contents of both clipboards clip = run_cmd("xclip -o -sel clip".split()) primary = run_cmd("xclip -o -sel primary".split()) # write to temp file contents # of both clipboards appended temp_file = "/tmp/append.clip" f = open(temp_file, "w") f.write( clip + primary ) f.close() # Read the new contents into clipboard run_cmd(("xclip -sel clip " + temp_file).split()) # clean up os.remove(temp_file) 

笔记:

  • 必须通过sudo apt-get install xclip
  • 我已经为使用Unity桌面的Ubuntu编写了一个剪贴板管理器指示器 ,它可以使用正则表达式( sed和python的re样式)将重复的字符串附加到剪贴板。 例如,如果您经常需要反复追加相同的字符串,则可以使用以下python re regex:

在此处输入图像描述

这是另一个使用简短Bash脚本的非常简单的方法。 首先确保安装了xclip。 然后按如下方式创建bash脚本:

 #!bin/bash p=$(xclip -selection primary -o) c=$(xclip -selection clipboard -o) new=$'\n' echo "$c$new$p" | xclip -selection clip 

让我们将这个文件命名为apndpc.sh并将其放在某个文件夹中,比如〜/ myscripts现在将用户定义的键绑定到此。 通过系统设置>>键盘执行此操作,然后单击快捷方式选项卡。 单击自定义快捷方式,然后单击+符号以添加所需的组合键。 在命令框中输入:

bash -c’bash~ / myscripts / apndclp.sh’

然后定义您的组合键。 我使用ALT + 3来触发动作。

这就对了。 您已准备好进行大规模复制操作。 使用普通的Ctrl + c(或右键单击并选择复制)来复制第一个文本块。 选择下一个块(仅选择NOT copy),然后按快捷键(ATL + 3)。 这会将所选文本附加到剪贴板。 继续这样做,直到你完成。 然后像往常一样粘贴,即。 CTRL + v(或righclick并选择粘贴)以转储最终累积的文本。

如果您不喜欢上述脚本中的字符串操作,请改用以下脚本:

 #!bin/bash # this is another version of clipboard append tool # here we use a temporary file to append highlighted text to the clipboard # the temporary file is deleted at the end of the operation tmpfile="file111000111" xclip -selection clipboard -o > $tmpfile # first dump the current clipboard to the tmpfile printf '\n' >> $tmpfile # then add new line xclip -selection primary -o >> $tmpfile # and finally add the highlighted text cat $tmpfile | xclip -selection clip # now read the file back into the clipboard rm $tmpfile # and remove the tempfile 

我使用一个名为clipit的剪贴板管理器。

然后每当我想看到键盘上的最后一些东西时,我都会在控制台上执行此操作:

 strings ~/.local/share/clipit/history 

它将打印由\n分隔的剪贴板历史记录。