9

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.)

1
  • Not that I know of, but `previous_command` or $(previous_command) come close. E.g. less `locate dmesg.boot ` .
    – Hennes
    Sep 29, 2013 at 22:50

5 Answers 5

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.

1
  • 1
    Possibly screen would be more useful than script. It should be possible to craft a screen macro which copies the last line of the scrollback buffer into the input.
    – rici
    Oct 1, 2013 at 16:41
8

I think the closest you'll get is:

$ do_something_with "$(!!|tail -1)"
2
  • good. i'll post my complete answer including the lead you gave me Oct 2, 2013 at 10:00
  • 1
    Note that this runs the command a second time which might not be desirable in some cases. Nov 12, 2013 at 15:47
2

http://www.gnu.org/software/bash/manual/bashref.html#Miscellaneous-Commands

shell-expand-line (M-C-e)

Expand the line as the shell does. This performs alias and history expansion as well as all of the shell word expansions (see Shell Expansions).

For example:

$ touch one two three four
$ echo `ls | tail -n1` 

ctrl+alt+e

$ echo two
1
  • Thanks a lot! This is actually the only true answer: OP wanted to have the output be in the command line (alias have it be editable).
    – phil294
    Dec 30, 2017 at 2:25
1

I hope this is what you asked for

ls -l | tail -1 | tee

enter image description here

2
  • it's not. i'm looking for "retrospective" solution, i.e. i dont want to add these arguments BEFORE each time i need the last line, i thought there's something that either remembers or reads the line above the prompt... Sep 30, 2013 at 10:13
  • actually, if I add this to ANY command, and set the response to a variable, it might actually be a good lead... Feb 2, 2014 at 12:36
1

A solution that works for me, albeit not 100% real answer, is based on rici's and glenn jackman's answers here, plus binding a key to that command.

Glenn's command will run the last program again, capturing it's last line and replacing itself with the line content on the command line:

"$(!!|tail -1)"

i want to make it clear: This trick will run the command once more, so, depends on the case, it could be harmful, slow, or plain wrong - based on the case.

Last thing was to bind key combo:

I used Alt+/ since its similar to the key-combo that gives the last typed argument Alt+.

bind '"^[/":"\"$(!!|tail -1)\""'

(see here for how key-binding works)

Now add the bind command to my profile (.bashrc or .profile or something).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .