Ubuntu – How to only append to clipboard (but not overwrite current data)

clipboardcopygnomeshortcut-keys

I have a rather large file, I need to copy the entire contents somewhere, but when I scroll down the page all the data I have selected becomes unselected. I could just copy and paste block by block, but I would find it much easier as there is a lot of data, to just be able to append the contents to the end of the current clipboard data. Is that possible?

That is so that I can have a keyboard shortcut which will enable me to copy this to the clipboard:

I am some nice new text.

When this is what is already there:

I am the old text.

And have it look like this when pasted:

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

So there are 3 things that I would really like from this (I would have 3 separate keyboard shortcuts to do this):

  1. Append the data to the end of the clipboard and have it put in a RETURN before it (as shown in the example above).

  2. Append the data to the end of the clipboard but have it so that there is not RETURN before it so that it would continue on on the same line initially.

  3. Have all this but so that the data is put at the beginning of the clipboard before all the data which is currently there.

I am running Ubuntu GNOME 16.04 with GNOME 3.20.

Best Answer

It is simple, but you need to install the tool xsel first:

sudo apt-get install xsel

TL;DR: Here are the commands you probably want to use for your shortcuts in the end. I am using the versions with printf everywhere for uniformity and easier customization, even if a simpler variant would have been enough:

  • Append selection to end of clipboard directly:

    bash -c 'printf "%b%b" "$(xsel -b)" "$(xsel)" | xsel -ib ; xsel -c'
    
  • Append selection to end of clipboard after a line break:

    bash -c 'printf "%b\n%b" "$(xsel -b)" "$(xsel)" | xsel -ib ; xsel -c'
    
  • Append selection to beginning of clipboard directly:

    bash -c 'printf "%b%b" "$(xsel)" "$(xsel -b)" | xsel -ib ; xsel -c'
    
  • Append selection to beginning of clipboard after a line break:

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

They are all including the primary buffer reset after appending to the clipboard to prevent double appending the same content. If you do not want that, remove the ; xsel -c from the end of each command.


Long explanation:

You have to know that X contains 3 buffers, the primary selection, the secondary selection and the clipboard.

You know the clipboard from Ctrl+C, Ctrl+V etc. It's the buffer you normally use to copy and paste stuff.

The primary selection though is the buffer that always automatically contains the text you select, no matter which window it is in and without any additional user interaction.
We just have one problem: The buffer gets updated the moment you select a text snippet, but it does not get cleared when you click anywhere else to cancel the selection. It will still contain the content of your last selection.

The secondary selection is only used by few programs and not interesting for us here.


That means we can mimic the behaviour of Ctrl+C with this command below which copies the primary selection (last highlighted text) to the clipboard:

xsel | xsel -ib

xsel without any arguments prints the primary selection's content to STDOUT. xsel -ab writes (-i) the data from STDIN to the clipboard (-b).


To directly append data to the current clipboard content (without line break in between) instead of replacing it, we use the -a option instead of -i. This command will append the last selected text snippet to the current clipboard content:

xsel | xsel -ab

If you really want an additional line break or any other formatting, we can pipe the data through printf or any other tool that you want to use to process it. Here's an example that reads both the last selection and the current clipboard content and joins them together using a newline:

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

xsel -b returns the current clipboard content. The format string of printf uses %b as placeholder for the arguments, \n represents a line break. You can find out more about printf by typing man printf.

By switching the two arguments in the end of the string, you can reverse their order and append to the beginning instead of the end.


If you want to avoid appending the same data to the clipboard twice accidentally (you will have to select it again if you want to append it twice!), you can clear the primary selection buffer manually after the command has been performed using this:

xsel -c

Simply run that after the basic clipboard appending command, like that:

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

So knowing all this, you can write commands for your keyboard shortcuts that do exactly what you want, but remember that our one-liners all make heavy use of Bash features like piping, so you need to run them with Bash:

bash -c 'COMMAND'

See the TL;DR section at the top of the answer for a command list suitable for creating shortcuts.