rename is a command part of util-linux package. As its name suggests, it’s for renaming files; more specifically, batch or bulk renaming with pattern.
There is another variation of rename, prename, which is written in Perl and can be found on Debian-based distributions. The Perl and util-linux versions are fundamentally different. Perl one is based on regular expression and util-linux’s is not.
Keep in mind, rename does not recognize regular expression, only simple pattern (literal string). Since it’s not regular expression, therefore there is no greedy substitution, that is no s/pattern/replacement/g in regular expression term.
The most serious caveat might the file overwrite, for example:
$ touch a b $ rename a b *
The b file would be replaced by file a and there is no warning about it.
The command is used as:
rename pattern replacement file(s)
pattern is the string which is to be replaced with replacement, and files are the files are to be processed one by one with the pattern.
rename doesn’t have many options, it has only one -v as for verbosity. Which outputs what it has done, for example:
$ touch foo.example $ rename foo bar * `foo.example' -> `bar.example'
There are some times that filenames with numbers. If I recall correctly, there is a feature of numbering files in Windows File Explorer. It’s a good feature and example for this, but somewhat problematic when loading those files in a program. The filenames—and the problem—may look like:
$ ls -1 *.ext file (1).ext file (10).ext file (2).ext ... file (9).ext
As you can see, the sorting isn’t by the numbers but alphabetically. To resolve it, we prefix a zero:
rename '(' '(0' *'('?')'*.ext
The Bath Pathname Expansion, *'('?')'*.ext, only matches files with single character within filename. You can use *'('[0-9]')'*.ext to be more precise, but it’s not necessary. rename then adds additional zero after left parenthesis.
Like said Caveats, rename can’t use regular expression, or this would be simpler and more clear.
If you need to prefix something before filenames, run:
rename '' 'PREFIX ' *
The empty string matches right away, that is beginning of a filename, then it’s replaced with replacement.
If the file is like MAIN.EXT, then it’s fairly simply, for example:
rename '.' ' APPEND.' *.ext
But it is impossible if appending to entire filename and there is no common suffix. For example, appending to files like foobar and dummy.
From time to time, there is a need for nitpicking on file extension for personal preferences. For examples,
foobar.JPG -> foobar.jpg foobar.jpeg -> foobar.jpg foobar.htm -> foobar.html foobar.mkd -> foobar.md
With rename, simply supply two extensions to it, for instance,
$ rename .JPG .jpg *.JPG
Like said Caveats, the substitution only occurs once and you can not control where the occurrence can be like ^ or $ in regular expression. So, for some funky filenames like foobar.JPG.mkd, it may or may not be giving you some unexpected (unacceptable) results.
By now, you should have no problem with string removal—replacement is empty string—or character replacement. As said in Caveats, there is no greedy substitution, hence you can’t actually replace all spaces with dashes effectively as you want to with:
rename ' ' '-' files
Every run of rename can only replace once. That is said, if a filename with five spaces, you must run rename five times. This should be enough to say, it isn’t ideal to use rename for this kind of case. You may want to consider other renaming methods or just write a simple one-liner in shell script.