1

Can't figure out if this is possible, but it sure would be convenient.I'd like to get the output of a bash command and use it, interactively, to construct the next command in a Bash shell. A simple example of this might be as follows:

> find . -name myfile.txt
/home/me/Documents/2015/myfile.txt

> cp /home/me/Documents/2015/myfile.txt /home/me/Documents/2015/myfile.txt.bak

Now, I could do:

find . -name myfile.txt -exec cp {} {}.bak \;
or
cp `find . -name myfile.txt` `find . -name myfile.txt`.bak
or
f=`find . -name myfile.txt`; cp $f $f.bak

I know that. But sometimes you need to do something more complicated than just add an extension to a filename, and rather than getting involved with ${f%%txt}.text.bak etc etc it would be easier and faster (as you up the complexity more and more so) to just pop the result of the last command into your interactive shell command line and use emacs-style editing keys to do what you want.

So, is there some way to pipe the result of a command back into the interactive shell and leave it hanging there. Or alternatively to pipe it directly to the cut/paste buffer and recover it with a quick ctrl-v?

2 Answers 2

4

Typing M-C-e expands the current command line, including command substitutions, in-place:

$ $(echo bar)

Typing M-C-e now will change your line to

$ bar

(M-C-e is the default binding for the Readline function shell-expand-line.)


For your specific example, you can start with

$ cp $(find . -name myfile.txt)

which expands with shell-expand-line to

$ cp /home/me/Documents/2015/myfile.txt

which you can then augment further with

$ cp /home/me/Documents/2015/myfile.txt

From here, you have lots of options for completing your command line. Two of the simpler are

  1. You can use history expansion (!#:1.txt) to expand to the target file name.
  2. You can use brace expansion (/home/me/Documents/2015/myfile.txt{,.bak}).
Sign up to request clarification or add additional context in comments.

3 Comments

If you use vi mode, shell-expand-line is not bound to anything by default, but you can use the bind command to fix that. I have it bound to *(in vi's normal mode), so I can hit ESC-* to do this. (bind -m vi-command '*:shell-expand-line')
Thanks, that will work for me. I don't have the keybinding in xterm by default, but I can create it. I just need the output on the command line so I can kill (ctrl-k) it into my readline kill-ring and then ctrl-yank it back whenever I need it.
Incidentally, since I am using a touchpad it is very awkward for me to do this the mouse-way. It requires selecting the previous line (hold thumb down and drag precisely), followed by middle-click (three finger tap at exactly the same time). Wonder how many hours I've lost to this maneuver.
2

If you are on a Mac, you can use pbcopy to put the output of a command into the clipboard so you can paste it into the next command line:

find . -name myfile.txt | pbcopy

On an X display, you can do the same thing with xsel --input --clipboard (or --primary, or possibly some other selection name depending on your window manager). You may also have xclip available, which works similarly.

1 Comment

yes! if I use --primary instead of --clipboard, it ends up in my x selection buffer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.