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

7 gnome shortcut-keys clipboard copy

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

这样我就可以有一个键盘快捷键,使我能够将其复制到剪贴板:

I am some nice new text.
Run Code Online (Sandbox Code Playgroud)

当这是已经存在的东西时:

I am the old text.
Run Code Online (Sandbox Code Playgroud)

粘贴时看起来像这样:

I am the old text.
I am some nice new text.
Run Code Online (Sandbox Code Playgroud)

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

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

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

  3. 拥有所有这些,以便将数据放在剪贴板的开头,然后放在当前存在的所有数据之前。

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

Byt*_*der 9

很简单,但是你需要先安装这个工具xsel

sudo apt-get install xsel
Run Code Online (Sandbox Code Playgroud)

TL;DR:以下是您最终可能希望用于快捷方式的命令。我正在使用printf随处可见的版本以实现一致性和更轻松的定制,即使更简单的变体就足够了:

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


长解释:

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

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

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

二级选择只被少数程序使用,对我们来说并不有趣。


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

xsel | xsel -ib
Run Code Online (Sandbox Code Playgroud)

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


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

xsel | xsel -ab
Run Code Online (Sandbox Code Playgroud)

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

printf "%b\n%b" "$(xsel -b)" "$(xsel)" | xsel -ib
Run Code Online (Sandbox Code Playgroud)

xsel -b返回当前剪贴板内容。格式字符串printf使用%b作为占位符参数,\n代表一个换行符。您可以printf通过键入了解更多信息man printf

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


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

xsel -c
Run Code Online (Sandbox Code Playgroud)

只需在基本的剪贴板附加命令之后运行它,就像这样:

printf "%b\n%b" "$(xsel -b)" "$(xsel)" | xsel -ib ; xsel -c
Run Code Online (Sandbox Code Playgroud)

因此,了解所有这些后,您可以为键盘快捷键编写完全符合您要求的命令,但请记住,我们的单行程序都大量使用了 Bash 功能,例如管道,因此您需要使用 Bash 运行它们:

bash -c 'COMMAND'
Run Code Online (Sandbox Code Playgroud)

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


Ser*_*nyy 5

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

在此处输入图片说明

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

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

用法示例:

  1. 突出显示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)
Run Code Online (Sandbox Code Playgroud)

笔记:

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

在此处输入图片说明