1

Let's say I have a folder located on ~/question with 4 files:

$ ls 
_file1  _file2  _file3  _file4

I've realized that it's possible to open folders with Vim and it'll list the file names of all the files that are inside this folder. For example, on Linux if I try to open Vim with vim ~/question I'll have something like the following:

enter image description here

I've seen the F1 help and I've realized that there is a R command for renaming files... But it doesn't work very well since I can't create macros while renaming files like that. The commands there work a lot different from the traditional Vim commands.

However, I've realized that if I try to rename those files with :%s/_/-/g (after running :set modifiable) it actually works and it renames all files substituting _ to - on all of them... The only problem is that I can't go out and save the changes after, I see the error "readonly" option is set(add ! to override)...

So, is there any way of solving that reading only problem while editing folders? Is it really possible to rename files of a folder on Vim directly using regular expressions?

2

There are a number of tools that allow you to rename files in a Vim buffer in this way. mvi is the one that I use.

It takes the paths of the files that you want to rename as arguments, so, for example, to edit the names of all the Python files in your current directory, you would invoke it from your shell with:

mvi *.py

Vim will open with a buffer containing all the files that match the *.py glob and you can make edits using any Vim commands. Then you just save the buffer and quit and the changes are applied.

See also this page on the Vim tips wiki for a shell-based solution.

2

One alternative is to use https://github.com/ipod825/vim-netranger . It replaces netrw, and uses vim key bindings to do actions on the files. In this case, you can go to insert mode with i and change the file name. What will work is to do ctrl-o and from there :%s. Alternatively, use :g to enter i repeatedly and do the change.

1

It is possible to use netrw (the default explorer when you open directories for editing) to execute bulk rename operations.

You can do that by first marking the files, and then using a s/// substitution when prompted for a replacement in the rename operation.

Beware: This gets really heavy in its use of regexps. It's also quite strict in how you get all the details correctly. You also don't have "undo" available, if you make any mistakes. And if you happen to get some details wrong and there are name clashes, you may end up overwriting existing files, with possibly no good way to recover them other than restoring from a backup.

In your particular case, replacing _ with - at the start of the filenames, you can do that with this sequence of operations:

  • Use the mr command to mark a series of files, selecting them based on a pattern.
  • You'll be prompted with Enter regexp: but note this command actually wants a glob instead! So enter _* to mark all files with a name starting with underscore. (You would use something like *.txt to mark all files with a "txt" extension.)
  • Use the R command to rename files. netrw will prompt you about the first file, so it will ask you about renaming _file1 to what? But you can actually use a s/// expression here, which will then apply to all marked files.
  • Press Control-U to delete the current replacement (or backspace as many times as needed), and enter s/_\(.*\)/-\1/ in its place. Once you press ENTER, all your files will be renamed as you expect.

Note that:

  • You need to have the final slash in the s/// expression for this to work (that's usually not the case with the :s command, but it's the case here.)
  • You need the pattern to match the whole filename. You can't just use s/_/-/ here unfortunately.
  • Which means you typically need at least one capture group, such as \(.*\), which you then refer to using \1 on the replacement side.

The last couple of constraints mean it's really hard to use this feature to, for example, replace all underscores with hyphens...

But it can be used to change a prefix in files, or to change file extension. Even in those cases, having to deal with capture groups makes this feature pretty clunky, so you're probably better off using a different tool for your bulk rename operations.

See also:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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