3

I have multiple files to edit. I have to make certain changes, like copying some lines based on patterns and then I have to insert some text at different places. I am planning to use vim to automate my task. I have written this script

gg
i
some text to add
some more text to add
<esc>
:%s/text/TEXT/g
:wq

But it just opens up the vim editor and inserts even the commands in the file and then I have to manually remove the following text

<esc>
:%s/text/TEXT/g
:wq

and save the file.

I am invoking the following command:

vi -s vimscript mytextfile

I have used vim scripting earlier to do other things than inserting text like searching and replacing or copy-pasting patterns etc.

4 Answers 4

5

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.
Sign up to request clarification or add additional context in comments.

Comments

3

From :help -s:

-s {scriptin}   The script file "scriptin" is read.  The characters in the
                file are interpreted as if you had typed them.  The same can
                be done with the command ":source! {scriptin}".  If the end
                of the file is reached before the editor exits, further
                characters are read from the keyboard.  Only works when not
                started in Ex mode, see |-s-ex|.  See also |complex-repeat|.
                {not in Vi}

Think of it as a macro. This is how your vimscript file should look:

Osome text to add^Msome more text to add^[:%s/text/TEXT^M:wq^M

The ^M special character is a literal <CR> and is obtained with <C-v><CR>.

The ^[ special character is a literal <Esc> and is obtained with <C-v><Esc>.

1 Comment

How do I search within the text for, say, /findthis in the script? then I want to delete all text that precedes the first searched location.
3

Why using vim to automate that kind of task whereas there are many commands or shell languages which are excellent and more efficient to do it ? You could use other tools instead of vim to automate your task.

You could try to use sed for exemple :

[ ~]$ cat file
Here is a file
[ ~]$ echo "some text to add" >> file
[ ~]$ echo "some more text to add" >> file
[ ~]$ cat file
Here is a file
some text to add
some more text to add
[ ~]$ sed -i "s/text/TEXT/g" file
[ ~]$ cat file
Here is a file
some TEXT to add
some more TEXT to add

EDIT : There are different ways to insert some text at the top of a file.

Using a temporary file :

 echo "some text to add" > tmp.txt
 cat file.text >> tmp.txt
 mv tmp.text file.txt

Using sed :

sed -i "1isome text to add" file.text # or
sed -i "1s/^/some text to add\n/" file.txt

Using subshell :

echo -e "some text to add\n$(cat file.txt)" > file.txt

3 Comments

Does sed support g type features that are supported by vi? I don't know. I am more accustomed to vi so I feel at home. Anyway thanks for pointing out the efficiency issue though.
@TemPora I've edited my post to add some tips about inserting some text at the top of a file. I guess that's the equivalent of gg vim command.
Moreover, I think that's not a good idea to use vim to automate that kind of task on a large set of file.
2

I find it more natural to use a standard Vim script, not a normal mode script. You can invoke it using:

vim -c "source vimscript" mytextfile

Your vim script will need a little update to work using this approach. It will look something like:

1
i
some text to add
some more text to add
.
%s/text/TEXT/g
wq

Comments

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.