How to rename files based on pattern in Linux
Summary
How to rename files in bulk - based on a pattern / string - using a shell command that leverages Bash's parameter expansion. Practical examples and command break downs. Highlights the advantages over external tools like rename
or sed
.
Introduction #
Renaming files in bulk is a common and tedious task when managing files. In this article I will demonstrate how to rename files by replacing specific parts of their filenames using a simple shell command.
I will work with example files and explain how the used commands works, making it easy to adapt them for similar tasks.
The examples in this article refer to the following three example files:
$ tree
.
├── foo-example-1.txt
├── foo-example-2.txt
└── foo-example-3.txt
Single Change on Multiple Files #
The goal is to rename the foo
part in each file name to bar
. So that the list looks like this:
$ tree
.
├── bar-example-1.txt
├── bar-example-2.txt
└── bar-example-3.txt
The following shell
command renames all .txt
files in the current directory by replacing occurrences of the string foo
with bar
in their filenames.
for file in ./*.txt ; do mv "$file" "${file//foo/bar}" ; done
Breakdown:
for file in ./*.txt ; do ... ; done
- This
for
loop iterates over all.txt
files in the current directory (./
). - The
file
variable holds the filename of each file during each iteration.
- This
mv "$file" "${file//foo/bar}"
mv
is the command to rename (move) files."$file"
is the current file’s name (quoted to handle spaces or special characters)."${file//foo/bar}"
is a parameter expansion that replaces all occurrences offoo
withbar
in the filename.
The replacement is case-sensitive.
This option is ideal. It makes use of Bash’s Shell Parameter Expansion and does not require the rename
or sed
packages. Both packages are often not preinstalled (Ubuntu), or even only available in user repositories, e.g. rename
in Arch Linux.
Multiple Changes on Multiple Files #
Let us adjust the above command by applying two replacements sequentially within the loop, so that not only foo
is renamed to bar
but also example
will be renamed to sample
. Here’s the modified command:
for file in ./*.txt; do
new_file="${file//foo/bar}" # Replace 'foo' with 'bar'
new_file="${new_file//example/sample}" # Replace 'example' with 'sample'
mv "$file" "$new_file" # rename file
done
Breakdown:
${file//foo/bar}
: Replacesfoo
withbar
.${new_file//example/sample}
: Applies the second replacement, changingexample
tosample
.mv "$file" "$new_file"
: Renames the file using the updated name.
The replacement is case-sensitive.
After using the command, the files will look like this:
$ tree
.
├── bar-sample-1.txt
├── bar-sample-2.txt
└── bar-sample-3.txt
Case-Insensitive Command #
To make the command case-insensitive, you can use bash’s built-in features like shopt -s nocaseglob
, which makes filename expansion case-insensitive.
for file in ./*.txt; do
# Convert filename to lowercase using `tr`
lower_file=$(echo "$file" | tr '[:upper:]' '[:lower:]')
# Perform replacements
new_file="${lower_file//foo/bar}"
new_file="${new_file//example/sample}"
# Rename the file
mv "$file" "$new_file"
done
shopt -u nocaseglob # Disable case-insensitive file matching
Breakdown:
shopt -s nocaseglob
: Enables case-insensitive matching for files.tr '[:upper:]' '[:lower:]'
: Converts the entire filename to lowercase.${new_file//foo/bar}
and${new_file//example/sample}
: Perform string replacements.mv "$file" "$new_file"
: Renames the file.
Further readings #
Sources and recommended, further resources on the topic:
- Bash Manual: Shell Parameter Expansion
- Bash Manual: Looping Constructs
- Bash Manual: The Shopt Builtin
- Wikipedia: mv command
- Wikipedia: tr command
License
License: How to rename files based on pattern in Linux by Jonas Jared Jacek is licensed under CC BY-SA 4.0.
This license requires that reusers give credit to the creator. It allows reusers to distribute, remix, adapt, and build upon the material in any medium or format, for noncommercial purposes only. To give credit, provide a link back to the original source, the author, and the license e.g. like this:
<p xmlns:cc="http://creativecommons.org/ns#" xmlns:dct="http://purl.org/dc/terms/"><a property="dct:title" rel="cc:attributionURL" href="https://www.ditig.com/instructions/how-to-pattern-based-rename-multiple-files">How to rename files based on pattern in Linux</a> by <a rel="cc:attributionURL dct:creator" property="cc:attributionName" href="https://www.j15k.com/">Jonas Jared Jacek</a> is licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="license noopener noreferrer">CC BY-SA 4.0</a>.</p>
For more information see the DITig legal page.