How to insert the last output line into the command line?

Does bash provide a way to insert the last output line of the previous command into the command line?

For example, suppose I just ran ls -1 and the output was

file1
file2
file3

Is there a key combination that can insert the text file3 at the cursor position?

(Similar to Alt + ., which inserts the last argument of the previous command, but here I want to paste the output, not the command itself.)


Solution 1:

Here's an incomplete solution. I think it could be made to work, more or less.

First, we arrange to capture all keyboard output by running inside a script environment. (There are lots of problems with that; see below.) We need to pass the -f flag to script so that it flushes output immediately to the typescript file. We also choose a filename in /tmp:

script -f /tmp/typescript

Inside the scripted environment, we define a keyboard shortcut to extract the last line of the typescript file and push it into the history: (I bound the commands to Ctl+yCtl+y on the assumption that you don't type that very often. A bug in bash prevents you from binding commands to sequences longer than two bytes, and that eliminates all the Fn keys, for example.)

bind -x '"\C-y\C-y":history -s $(tail -n2 X|head -n1)'

Now, to insert the last line of output into the current command line, we "just" need to type ctl-y ctl-y ! ! esc ^ which will copy the last line of output into the history, then insert a history expansion, then trigger history expansion. There's probably a better way of doing that, but that sort of works. It's a lot of keypresses, though, so we assign it to a keyboard macro:

bind '"\eOP":"\C-y\C-y!!\e^"'

Up to a point, that works. However, now we need to deal with the ugliness of script, which saves the output precisely as it was generated, VT-102 control codes and all. It saves what you typed, precisely as you typed it, including all the mistakes you backspaced over, the backspaces, and the new characters. It saves the carriage return (ctl-m) which is sent at the end of every line. In short, it's not really text you'd like to have inserted into a command line.

Conceptually, though, it works. All it needs is a better tool for saving session output, and perhaps a more elegant way of inserting the result of calling a shell-command than pushing it into the history and then getting it back out again.

Solution 2:

I think the closest you'll get is:

$ do_something_with "$(!!|tail -1)"

Solution 3:

I hope this is what you asked for

ls -l | tail -1 | tee

enter image description here