Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have a bunch of directories that each hold one *.txt file in it (and other non *.txt files).

I'd like to rename those files recursively from the command line, basically *.txt to info.txt. So all *.txt files should be renamed to info.txt. There is always only one .txt file in each directory.

I have been looking at multiple questions here (and elsewhere) that seem similar, but either they focus to change the extension, or they do not work recursively,...

Any help would be very much appreciated. Platform: Linux or MacOSX.

share|improve this question

3 Answers 3

up vote 3 down vote accepted
find ~/dir -type f -name "*.txt" -not -name "info.txt" \
           -execdir mv -v {} info.txt \;

Alternatively:

find ~/dir -type f -name "*.txt" -not -name "info.txt" \
| while read -r file; do
    mv "$file" "${file%/*}/info.txt"
done
share|improve this answer
    
Thanks for the super quick response ... this worked like a charm!! :) (without the \ at the end of the first line - but that's me not paying attention when doing a copy/paste) –  Hanzaplastique May 12 '13 at 17:41
    
@Hanzaplastique The \ escapes the newline, so you can copy-paste the entire code block to your terminal, or into a shell script. –  slhck May 12 '13 at 17:43
    
Note that -execdir is not specified by POSIX, so not all versions of find will have it. This will certainly work on most linuxes, since they tend to use GNU find, but I don't know if whatever version OSX uses has -execdir (you may need to use the POSIX-specified-but-less-safe -exec instead). –  evilsoup May 12 '13 at 17:54
1  
The \ caused an error message on MacOSX, taking it out resolved it :-) Thanks again for the quick answer! Just wished I would have counted on those stupid hidden MacOS files (like ._info.txt). –  Hanzaplastique May 12 '13 at 19:05
1  
Note for Mac users: find . -name "._*" -exec rm '{}' \; will remove those. –  Hanzaplastique May 12 '13 at 19:10

You can also use the rename utility from Ubuntu, which accepts a Perl expression to modify the file names.

find . -iname "*.txt" | rename "s/[^\/]+\.txt$/info.txt/"
share|improve this answer
    
Which rename does this apply to? Also note that this will most probably break if files or paths contain spaces. –  slhck May 12 '13 at 20:59
    
I don't know the version, there's no -v option. I tested it on Ubuntu 12.04 and it works, even if the a file has space in its name or path, since find doesn't escape spaces. I prefer the grawity's solution, but I didn't read it before. –  Lucas Malor May 12 '13 at 21:12
    
I'm just asking because there exist various tools that call themselves rename, e.g. plasmasturm.org/code/rename and ss64.com/bash/rename.html. –  slhck May 12 '13 at 21:18
    
It's exactly this one: manpages.ubuntu.com/manpages/dapper/man1/prename.1.html I think it's a tool provided by perl guys. –  Lucas Malor May 12 '13 at 21:34
    
Yet another one :) I added a link to that manpage to your post in case someone gets confused over the options. –  slhck May 12 '13 at 21:36

grawity's answer is the fastest way and maybe the more "correct" one, but there are also some GUI based tools that can perform file renaming tasks with an easy interface and support for regular expressions: Krename (KDE based), GPRename and pyRenamer (Gnome base).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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