Vim. Change multiple files at once. Detailed example with comments

    There are situations when you need to perform some sequence of actions simultaneously in several files. Of course, you can use different tools for this (offhand: bash + sed / awk, python / perl, ...) - some will be less suitable for the task, some more. Now we will consider an example of solving one such simple task using the Vim editor tools.

    Consider a simple example: inserting a line at the beginning of each file.

    In the course of this simple task, some nuances of using Vim may arise, the knowledge of which may be necessary and useful in working with this wonderful editor. At the same time, this example will provide an opportunity for beginners to consolidate the use of Vim registers and macros in their practice.

    So let's get started:

    1. Open in the editor all the files in which you need to make changes:

    $ vim -o file1.txt file2.txt file3.txt

    The -o option allows you to open each file in a separate window. The launch with this option in the example was made not only for clarity (all changes will be visible immediately), but also based on one more point, which will be discussed below.

    2. We write down the sequence of actions that need to be done on the files in the macro:

    qm1GOFirst linequ

    qm - start of macro recording in the register m
    1G - go to the first line of the file
    O (capital letter O) - insert a line before the current line with the transition to edit mode
    The first line - the contents of the first line
    - exit editing mode
    q - end macro recording
    u - discard changes in the current window to avoid duplication of changes made

    3. Run macro m in all windows

    :: windo normal @m

    windo - command to run the vim command in all windows
    normal - command to run the command vim normal mode from the command line, that is, two macro start commands are equivalent:
    : normal @m

    If we just did this
    :: windo @m
    we would get the error message “This is not an editor command”
    in fact we would each window did the following
    :: @m
    which is incorrectas we run the normal mode command on the command line. As a result, we can receive either an error message or unpredictable actions of the editor.

    There are commands similar to : windo ::
    : tabdo
    : bufdo

    The first command is : argdo . A powerful command that allows you to execute a command in a list of files specified as a named argument. We will not consider it here.
    The second command is : tabdo . It is completely similar to our windo, but it does all the work on all open tabs. There is one point worth mentioning here: in each tab there can be several windows. So, the changes will only be in the current window of each tab!
    Well, finally, the third team - : bufdo . Executes a command on all buffers. But there is one caveat when using it. The bufdo command itself will be executed only in the current buffer and will fail if the “useful” command (the one that bufdo runs and which should be executed in each buffer) changes the text.

    For example, this way::
    bufdo normal G
    will execute normally in all buffers,
    but like this
    :: bufdo normal GoEnd file will
    already fail. To make it work you need to do this
    :: bufdo! normal GoEnd file

    Actually that's all for today. For my first post on the hub, please do not kick. Corrections, additions, comments are welcome.

    Also popular now: