Linux: remove file extensions for multiple files

Solution 1:

rename is slightly dangerous, since according to its manual page:

rename will rename the specified files by replacing the first occurrence of...

It will happily do the wrong thing with filenames like c.txt.parser.y.

Here's a solution using find and bash:

find -type f -name '*.txt' | while read f; do mv "$f" "${f%.txt}"; done

Keep in mind that this will break if a filename contains a newline (rare, but not impossible).

If you have GNU find, this is a more solid solution:

find -type f -name '*.txt' -print0 | while read -d $'\0' f; do mv "$f" "${f%.txt}"; done

Solution 2:

I use this:

find ./ -name "*.old" -exec sh -c 'mv $0 `basename "$0" .old`.new' '{}' \;

Solution 3:

The Perl version of rename can remove an extension as follows:

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

This could be combined with find in order to also do sub-folders.

Solution 4:

You can explicitly pass in an empty string as an argument.

rename .old '' *.old

And with subfolders, find . -type d -exec rename .old '' {}/*.old \;. {} is the substitute for the entry found with find, and \; terminates the arglist for the command given after -exec.