This question already has an answer here:

I have a couple of files with ".old" extension.
How can I remove the ".old" extension without remove the file?

I can do it manually but with more work:

mv file1.key.old file1.key
mv file2.pub.old file2.pub
mv file3.jpg.old file3.jpg
mv file4.jpg.old file4.jpg


The command will work with other extensions too?


mv file1.MOV.mov file1.MOV
mv file2.MOV.mov file2.MOV
mv file3.MOV.mov file3.MOV


or better:

mv file1.MOV.mov file1.mov
mv file2.MOV.mov file2.mov
mv file3.MOV.mov file3.mov


marked as duplicate by don_crissti, Archemar, user181255, Jeff Schaller, Eric Renouf Apr 21 '17 at 16:27

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


Use bash's parameter substitution mechanism to remove matching suffix pattern:

for file in *.old; do
    mv -- "$file" "${file%%.old}"
  • 2
    This: for file in *.old; do mv "$file" "${file%%.old}"; done worked, Thanks – DiogoSaraiva Jan 21 '15 at 14:02

You didn't say what operating system you are using, but many Linux distributions have a rename command that you can use for this. There are actually two quite different rename commands - Debian and similar systems supply one while RedHat and similar supply another - but either one will work here.

Perl based rename on Debian, Ubuntu etc, see: prename manual.

Util-Linux rename on Redhat etc, see: rename manual.

On Debian and similar you can do:

rename 's/\.old$//' *


rename s/.MOV.mov/.mov/ *.*

On Redhat and similar you can do:

rename .old "" *

There are a lot of multi rename tools like http://file-folder-ren.sourceforge.net/

But I think the fastest way to rename is a simple script like:

for i in *.old
   mv -- "$i" "${i%.old}"

Note there is no error checking and if the target file exists it might be overwritten.

  • 2
    Add quotes, one space can ruin everything. – orion Jan 21 '15 at 13:31

With zsh, first load the zmv function with

autoload zmv

(you can do this from your .zshrc) then run

zmv -w '*.old' '$1'


zmv '(*).old' '$1'

If you want to restrict answers to shell (Bash) programming (rather than using a renaming tool), try this:

for oldname in *.old ; do
    if [ -e "$newname" ] ; then
        echo "Cannot rename $oldname because $newname exists." >&2
        mv -- "$oldname" "$newname"

I use quotes around $oldname and $newname because filenames can contain blanks.


Assuming "file" does not contain a "." :

ls -1 | while read line; do mv "$line" "`echo $line | cut -d'.' -f1,2`"; done

This example splits the filename by period and with -f you can control the fields to keep.

For your third example, you would use:

ls -1 | while read line; do mv "$line" "`echo $line | cut -d'.' -f1,3`"; done
  • 1
    If your folder contains files that are not to be renamed, add | grep <pattern> after ls -1 – Christian Bock Jan 21 '15 at 13:34
  • This removed more than I expected in file sub.class1.server.ca.pem.old become sub.class1 instead sub.class1.server.ca.pem Thanks – DiogoSaraiva Jan 21 '15 at 13:55
  • If it removed more than you expected, you failed to read the first line of my answer: assuming "file" does not contain a . – Christian Bock Jan 21 '15 at 14:31
  • 2
    ls | while read line; do … has no advantage over for line in *; do … and the downside of breaking over various file names. Do not parse the output of ls. – Gilles 'SO- stop being evil' Jan 21 '15 at 22:38

"Refinement" of Christian's solution ( https://unix.stackexchange.com/a/180275 ) using rev:

ls -1 | while read line; do mv "$line" "`echo $line | rev | cut -d'.' -f2- | rev`"; done

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