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 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 at 3:27
up vote 14 down vote accepted

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 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 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 at 7:57
  • @comphys src=a.txt; dst=b.txt; cp "$src" "$dst" && vi "$dst" – Kirill Bulygin Aug 15 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 at 12:44

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

example:

$ cat test.txt
function cp1() {
  source_file=$1
  destination_file=$2
  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 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 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 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 at 10:22
  • 1
    !$ may be better than ALT+. – Grump Aug 15 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 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 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 at 12:43

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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