20

I am writing a Bash script that runs a command-line program (Gromacs), saves the results, modifies the input files, and then loops through the process again.

I am trying to use Vim to modify the input text files, but I have not been able to find a way to execute internal Vim commands like :1234, w, x, dd, etc. from the .sh file after opening my input files in Vim ("vim conf.gro").

Is there a practical way to execute Vim commands from the shell script?

1
  • Are you sure you need to use vim rather than another editor such as sed? Can you use vim in its ex mode which does not use the full screen (and is better, therefore, for use in scripts)? What exactly are you trying to do in your scripted edit? Commented Sep 18, 2013 at 14:03

3 Answers 3

18

I think vim -w/W and vim -s is what you are looking for.

The "Vim operations/key sequence" you could also record with vim -w test.keys input.file. You could write the test.keys too. For example, save this in the file:

ggwxjddZZ

This will do:

Move to the first line,
move to the next word,
delete one character,
move to the next line,
delete the line, and
save and quit.

With this test.keys file, you could do:

vim -s test.keys myInput.file

Your "myInput.file" would be processed by the above operations, and saved. You could have that line in your shell script.

VimGolf is using the same way to save the user's solution.

Sign up to request clarification or add additional context in comments.

Comments

15

You can script Vim via the -c flag.

vim  -c "set ff=dos" -c wq mine.mak

However that only gets you so far.

  • From the commands you gave it looks like you are trying to run some normal commands. You will need to use :normal. e.g. :norm dd
  • Writing all this on the command line is asking for trouble. I suggest you make a Vim file (e.g. commands.vim) and then :source via -S.
  • You probably want to get good and conformable Vim's ex commands. Take a look at :h ex-cmd-index

So you will end up with something like this. With all your Vim commands inside of commands.vim.

vim -S commands.vim mine.mak

You may also want to look into using sed and/or awk for text processing.

1 Comment

This is exactly what I was looking for. I already had a solution for vim so I didn't want to pick another language/tool.
8

Alternatives

Unless you really need special Vim capabilities, you're probably better off using non-interactive tools like sed, awk, or Perl / Python / Ruby / your favorite scripting language here.

That said, you can use Vim non-interactively:

Silent Batch Mode

For very simple text processing (i.e. using Vim like an enhanced 'sed' or 'awk', maybe just benefitting from the enhanced regular expressions in a :substitute command), use Ex-mode.

REM Windows
call vim -N -u NONE -n -es -S "commands.ex" "filespec"

Note: silent batch mode (:help -s-ex) messes up the Windows console, so you may have to do a cls to clean up after the Vim run.

# Unix
vim -T dumb --noplugin -n -es -S "commands.ex" "filespec"

Attention: Vim will hang waiting for input if the "commands.ex" file doesn't exist; better check beforehand for its existence! Alternatively, Vim can read the commands from stdin. You can also fill a new buffer with text read from stdin, and read commands from stderr if you use the - argument.

Full Automation

For more advanced processing involving multiple windows, and real automation of Vim (where you might interact with the user or leave Vim running to let the user take over), use:

vim -N -u NONE -n -c "set nomore" -S "commands.vim" "filespec"

Here's a summary of the used arguments:

-T dumb           Avoids errors in case the terminal detection goes wrong.
-N -u NONE        Do not load vimrc and plugins, alternatively:
--noplugin        Do not load plugins.
-n                No swapfile.
-es               Ex mode + silent batch mode -s-ex
                Attention: Must be given in that order!
-S ...            Source script.
-c 'set nomore'   Suppress the more-prompt when the screen is filled
                with messages or output to avoid blocking.

3 Comments

I'm sure this is what I need but if I execute vim -c "dd" myfile.txt I get E492: Not an editor command: dd
@SridharSarnobat dd is a normal mode command, but the automation executes Ex commands. For deleting, you can choose between :delete, or use :normal! dd; you might also want to specify a target line number / range for delete. (Oh, and just for deleting full lines you don't need Vim - sed will do just fine.)
Thanks for the quick response, I had given up. I didn't know vim as well as I thought. Yes I could use sed but I'm trying to explore the power of vim beyond conventional usage and using it as a filter is one way to leverage more power of the Unix philosophy.

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.