27

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

(etc...)

The command will work with other extensions too?

example:

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

(etc...)

or better:

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

(etc...)

7 Answers7

31

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

for file in *.old; do
    mv -- "$file" "${file%%.old}"
done
jimmij
  • 47,140
8

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$//' *

or:

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

On Redhat and similar you can do:

rename .old "" *
kenorb
  • 20,988
bdsl
  • 195
  • 3
4

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
do
   mv -- "$i" "${i%.old}"
done

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

4

With zsh, first load the zmv function with

autoload zmv

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

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

or

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

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

for oldname in *.old ; do
    newname="${oldname%%.old}"
    if [ -e "$newname" ] ; then
        echo "Cannot rename $oldname because $newname exists." >&2
    else
        mv -- "$oldname" "$newname"
    fi
done

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

waltinator
  • 4,865
-1

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
Volker Siegel
  • 17,283
-1

"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