Executing a Command in Multiple Files in Vim
Tags: vim, files, substitute
Published: 2021-06-03 15:15:28

---
title: Executing a Command in Multiple Files in Vim
published: true
description: Executing a Command in Multiple Files in Vim
tags: vim, files, substitute
---

# Executing a Command in Multiple Files in Vim

When editing, you may need to execute a command across multiple files. For example, replacing all `let` with `const`. 

There are eight different ways you can do this in Vim.

```
:argdo    argument list (files)
:bufdo    buffers
:windo    windows in the current tab
:tabdo    tabs
:cdo      each item in the quickfix list
:cfdo     each file in the quickfix list
:ldo      each item in the location list
:lfdo     each file in the location list
```

Eight sounds like a lot of methods learn at once. However, the principle behind all of them is the same: make a list of what you want to change, then run the command to the entire member of that group, then save. The only difference is the scope of each entry.

Let's go over two of them here. Once you get a feeling how it works, using any of the methods above is just a matter of syntactical differences.

## Argument List

The argument list (`argdo`) uses file as the scope. To create an argument list consisting of `file1.txt`, `file2.txt`, and `file3.txt`, run `:args file1.txt file2.txt file3.txt` (you can also use the blob operator: run `:args *txt` to collect all txt files in the current directory, run `:args **txt` to collect all txt files recursively, run `:args z*txt` to collect all txt files in the current directory that starts with "z"). 

To check that you have the correct files, run `:args`. On the bottom screen, you should see something like `[file1.txt] file2.txt file3.txt`, indicating that you are currently on `file1.txt`. You can move around the argument list with `:next`, `:prev`, `:first`, `:last`, etc. Make sure that you are on the first entry before running the command.

Now run `:argdo %s/kale/pancake/g | update`. That's it. All kales inside `file1.txt`, `file2.txt`, and `file3.txt` are now substituted with pancakes. Sweet!

Command breakdown:
- `:argdo` performs the given command on all entry in the argument list. 
- `:%s/kale/pancake/g` is the substitute command. 
- `|` lets you to chain multiple commands together. 
- `update` saves each file.

## Quickfix List

Next, let's go over the quickfix list. If you not familiar, quickfix is Vim's special mode originally created to handle edit-compile-edit cycle error messages, but eventually evolved and used for all sorts of other things from displaying STDOUT when running async operations in [vim-dispatch](https://github.com/tpope/vim-dispatch), fuzzy searching in [fzf.vim](https://github.com/junegunn/fzf.vim), etc. For our purpose, think of it as **a list** of pointers to various location in your files.

Some commands in Vim automatically uses quickfix, like `:make`, `:grep`, and `:vimgrep`. 

If you need to list all occurrences of "veggies" inside any text file, run `:vimgrep /veggies/ **txt`. To see the quickfix matches, run `:copen` (quickfix open). To apply the substitute command to all quickfix matches, run `:cfdo %s/kale/pancake/g | update`. That's it. It follows a similar pattern like the argument list: collect-apply-save.

You can move around in a quickfix list with `:cfirst`, `:clast`, `:cnext`, `:cprev`, etc.

If you notice, on the list above you'll see `cfdo` and `cdo` quickfix operations. What's the difference? The difference is that `cfdo` is a per-file operator and `cdo` is a per-match operator. `cfdo` will run the command once per file and `cdo` will run the command once per match. 

If you have 5 matches for "veggies" inside `file1.txt`, running `:cfdo %s/kale/pancake/g` will run the command once while running `:cdo %s/kale/pancake/g` will run the command 5 times.

Since we are running a file-wide command (`%s`), it makes sense to run it only once per file.

## Conclusion

Vim's multi-file operations are useful to apply a change across multiple files. There are eight different ways to accomplish this, although the underlying principle is the same: collect-apply-save. Play around with the `args` / `argdo` and `vimgrep` / `cfdo` combos. Once you get comfortable with them, play around with the other commands.

Happy Vimming!

**Shameless disclaimer**: if you enjoy this, there's a 98.39% *(not scientifically proven)* you will also enjoy my **[Vim Cookbook: Gourmet Vim](https://leanpub.com/gourmetvim/)**. Check it out!