Say, I have 'a.txt'. I would like to copy the file and open the newly copied file using VI.

cp a.txt b.txt
vi b.txt

How to combine the two command in a command?

  • 13
    Hmm I’ve got to ask: why?! – Konrad Rudolph Aug 15 '18 at 10:20
  • @Rudolph Because of the curiosity and laziness. In addition, I think someday, I can apply the method to the other problems. – comphys Aug 26 '18 at 3:27

You can use vi itself to do the copy, by opening a.txt then saving the contents to b.txt (effectively copying it) and then switching to b.txt.

Putting it all together:

vi -c 'w b.txt' -c 'e#' a.txt

This is equivalent to running vi a.txt, followed by the :w b.txt command (inside vi), which will save the contents to a file named b.txt. But vi will still be editing a.txt at this point, so you follow up with the :e# command, which means "edit alternative file" (or "edit last file") and given vi has just touched b.txt, it will switch to editing that file.

  • Im not sure if vi has saveas (it may have come from vim) but it would shorten the command. – D. Ben Knoble Aug 15 '18 at 12:57
  • 3
    The :f command may be useful - that will just change the filename, and the user can write it the normal way at the end of the editing session with :wq. – Random832 Aug 15 '18 at 21:03

using && operator

cp a.txt b.txt && vi b.txt
  • Thank you. Is there any other way where I can type b.txt only once? – comphys Aug 15 '18 at 7:57
  • @comphys src=a.txt; dst=b.txt; cp "$src" "$dst" && vi "$dst" – Kirill Bulygin Aug 15 '18 at 9:43
  • 5
    @comphys Yes we actually can: cp a.txt b.txt && vi $_. Grump reminded me of this in another comment thread. – Hielke Walinga Aug 15 '18 at 12:44

You can write your own function and use that function. In the below example, you can use cp1 as a command.


$ cat test.txt
function cp1() {
  cp "${source_file}" "${destination_file}"
  vi "${destination}"

$ . ./test.txt    
$ cp1 a.txt b.txt 
  • I would like to know an ad hoc method which can be written in one command line. Anyway, thank you for the helpful answer. – comphys Aug 15 '18 at 8:47
  • 2
    @comphys If this is something you do frequently, why not define a function for it? If you don't do it enough to need a function, why does it even matter? – Barmar Aug 15 '18 at 17:27
  • @Barmar I don't frequently encounter this kind of situation. However, I wanted to know the answer to apply it to the other similar situation and the curiosity makes me ask! – comphys Aug 26 '18 at 3:08

If you want a way to save you typing you can use bash build in functionality to repeat the last word of the previous command. You can do this by ALT+.

> cp a.txt b.txt
> vi ALT+.

Very useful, and reminds you of the dot operator of vim.

Happy golfing.

  • 1
    Hmm this doesn’t seem to work for me. Is this a readline Emacs command (I’m working in vim mode)? – Konrad Rudolph Aug 15 '18 at 10:22
  • 1
    !$ may be better than ALT+. – Grump Aug 15 '18 at 12:30
  • @Grump That's indeed an interesting suggestion. I haven't thought of using that stuff. Actually $_ is more interesting, because it repeats the last executed command as opposed to the last command in history (that is what !$ does). But why would it be better. If we count keystrokes it is more and I also think the special symbols are a bit hard to reach. – Hielke Walinga Aug 15 '18 at 12:40
  • 1
    @KonradRudolph Indeed, this is for the emacs readline mode. Vim mode has the same functionality, but since . already has a function underscore is used here. ALT + Underscore also works in emacs mode btw. – Hielke Walinga Aug 15 '18 at 12:42
  • 2
    !$ is the last argument from the last command in history. I suggest it because it works in more shells and doesn't rely on keybindings – Grump Aug 15 '18 at 12:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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