Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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

share|improve this question
    
Not that I know of, but `previous_command` or $(previous_command) come close. E.g. less `locate dmesg.boot ` . –  Hennes Sep 29 '13 at 22:50

5 Answers 5

up vote 1 down vote accepted

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.

share|improve this answer
    
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 '13 at 16:41

I think the closest you'll get is:

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

I hope this is what you asked for

ls -l | tail -1 | tee

enter image description here

share|improve this answer
    
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... –  Berry Tsakala Sep 30 '13 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... –  Berry Tsakala Feb 2 at 12:36

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
share|improve this answer

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.