Recursively change file extensions in Bash
RegexLinuxBashShellShRegex Problem Overview
I want to recursively iterate through a directory and change the extension of all files of a certain extension, say .t1
to .t2
. What is the bash command for doing this?
Regex Solutions
Solution 1 - Regex
Use:
find . -name "*.t1" -exec bash -c 'mv "$1" "${1%.t1}".t2' - '{}' +
If you have rename
available then use one of these:
find . -name '*.t1' -exec rename .t1 .t2 {} +
find . -name "*.t1" -exec rename 's/\.t1$/.t2/' '{}' +
Solution 2 - Regex
None of the above solutions worked for me on a fresh install of debian 14. This should work on any Posix/MacOS
find ./ -depth -name "*.t1" -exec sh -c 'mv "$1" "${1%.t1}.t2"' _ {} \;
All credits to: https://askubuntu.com/questions/35922/how-do-i-change-extension-of-multiple-files-recursively-from-the-command-line
Solution 3 - Regex
If your version of bash
supports the globstar
option (version 4 or later):
shopt -s globstar
for f in **/*.t1; do
mv "$f" "${f%.t1}.t2"
done
Solution 4 - Regex
I would do this way in bash :
for i in $(ls *.t1);
do
mv "$i" "${i%.t1}.t2"
done
EDIT : my mistake : it's not recursive, here is my way for recursive changing filename :
for i in $(find `pwd` -name "*.t1");
do
mv "$i" "${i%.t1}.t2"
done
Solution 5 - Regex
Or you can simply install the mmv
command and do:
mmv '*.t1' '#1.t2'
Here #1
is the first glob part i.e. the *
in *.t1
.
Or in pure bash stuff, a simple way would be:
for f in *.t1; do
mv "$f" "${f%.t1}.t2"
done
(i.e.: for
can list files without the help of an external command such as ls
or find
)
HTH
Solution 6 - Regex
My lazy copy-pasting of one of these solutions didn't work, but I already had fd-find
installed, so I used that:
fd --extension t1 --exec mv {} {.}.t2
From fd
's manpage, when executing a command (using --exec
):
The following placeholders are substituted by a
path derived from the current search result:
{} path
{/} basename
{//} parent directory
{.} path without file extension
{/.} basename without file extension