Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I would like to change file extension from *.txt file to *.text file, tried using the basename command, but I am having trouble on changing more than 1 file, I am getting a basename: too many arguments Try basename --help' for more information error.

Any suggestion?

Here's my code:

files=`ls -1 *.txt`

for x in $files
do
mv $x "`basename $files .txt`.text"
done
share|improve this question
    
If you were instructed to use basename, you should have made that more explicit in your question. I have updated my answer to include that option. –  jasonwryan Aug 29 '11 at 7:49

8 Answers 8

up vote 26 down vote accepted

Straight from Greg's Wiki:

# Rename all *.txt to *.text
for f in *.txt; do 
mv -- "$f" "${f%.txt}.text"
done

Also see the entry on why you shouldn't parse ls.

Edit: if you have to use basename your syntax would be:

for f in *.txt; do
mv "$f" "$(basename "$f" .txt).text"
done
share|improve this answer
2  
There's some slightly advanced Bash syntax used here without explanation. I had to Google many things to understand this fully. To help others in my position, here are some references about globs (the *.txt syntax), the bare double dash --, and the use of the % symbol within the ${} construct. Until now I'd never encountered the latter two and hadn't known what was really happening with the former. –  Mark Amery Sep 21 '14 at 12:32
    
Look at Matthias Braun's answer below - much simpler, accomplishes the same thing. –  btk Mar 10 at 14:38

A simple command will do that for you, it replace every occurences of "txt" to "text" in all file matching "*.txt":

rename txt text *.txt
share|improve this answer
    
rename changes the first occurrence, so better make that rename .txt .text, but this still won't always work (e.g. it renames foo.txtx.bar.txt to foo.textx.bar.txt). –  Gilles Aug 29 '11 at 21:28
2  
It should be noted that not all systems have the same version of rename; on Debian and friends, the rename command is actually perl-rename and uses perl regexes. For that, the equivalent command would be: rename 's/.txt/.text/' *.txt. People should check the man rename on their system to find out which one they have. –  evilsoup Nov 13 '13 at 15:12

Here's how I change all the file extensions in the current directory on Debian.

rename "s/oldExtension/newExtension/" *.txt
share|improve this answer
    
Much simpler than the accepted answer, thank you! –  btk Mar 10 at 14:37
for f in *.txt
do
    [ -f "$f" ] && mv "$f" "${f%txt}text"
done
share|improve this answer

Based on the @Prince John Wesley answer, here is a simple bash script for changing all extensions of files in the current directory from ext1 to ext2. Also outputs names of the files being renamed.

#!/bin/bash
for f in *.$1
do
    [ -f "$f" ] && mv -v "$f" "${f%$1}$2"
done

Example usage (assuming the name of the script is change-ext):

change-ext ext1 ext2
share|improve this answer
    
To change extensions of files in directories recursively, replace the second line (for...) with two lines: shopt -s globstar and for f in **/*.$1. Requires Bash 4+. –  Denis Golomazov Feb 2 '12 at 10:40
rename "s/oldExtension/newExtension/" *.txt

Above works fine but limited to current directory. Try the command below, which is flexible with sub-directories. It will rename all .txt files under directory structure with a new extension.

find . -name "*.txt" -exec rename 's/.txt$/.newext/' {} \;
share|improve this answer
1  
rename can handle multiple files as argument, you can vastly speed things up by using + instead of \; if there are many such files –  Anthon Feb 17 at 8:57

let's say your files are scattered in various directory, Assuming that dirx is your parent directory, this can do the job using find:

for f in `find /dirx -iname '*.txt' -type f -print`;do  mv "$f" ${f%.txt}.text; done
share|improve this answer

In case you want to know what went wrong in your version: You used $files instead of $x in the basename command. So this should work (untested, though):

for x in *.txt
do
  mv "$x" "`basename '$x' .txt`.text"
done
share|improve this answer

protected by Community Feb 18 at 11:39

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

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