I have a bunch of files who's filename follows the pattern 'filename.ext'. eg:

filename .ext

I would like to rename all of these to remove the space before the .ext. eg:

filename.ext

I can find them all using

find * -type f -name'* .*'

but how can I then rename all these files?

link|improve this question

feedback

3 Answers

up vote 4 down vote accepted

Make a file named "renamethis.sh". Its contents should be:

#!/bin/bash
mv "$1" "$(echo $1 | sed 's/ \././')"

Set the executable bit: chmod a+x renamethis.sh. Then, run something like:

find /path/to/dir -name '* .*' -type f -print0 | xargs -0L 1 /path/to/renamethis.sh

YMMV, no warranty express or implied, etc.

FWIW, the spaces are what makes this strange; as long as you don't have other oddball characters in the files names, you're good to go with this approach. If you do, you may want to consider something like a scandir/readdir loop in Perl or PHP, but the above script is the first thing that came to mind.

link|improve this answer
Thanks that worked a treat. – Rich Apr 28 '11 at 3:25
Instead of using a custom script I suggest you to use the command rename which comes on every major distro. Check it's man page. – hmontoliu Apr 28 '11 at 10:40
2  
For "rename" to work, you'd have to have a complete list of all the extensions. So something like: for ext in $(find /path/to/dir -name '* .*' -type f | sed 's/.* \.//;s/ .*//'); do rename " .$ext" .$ext /path/to/dir/*\ .$ext; done. Without testing, though, not sure if rename is going to play nice with that glob, and it seems like a roundabout way to use a specific tool, so I think I still prefer my approach in circumstances where there's more than one extension that needs to be changed. – BMDan Apr 28 '11 at 18:23
2  
for exaple given this tree structure and several files with "any number of spaces prior to a dot extension" as follows: mkdir -p a/deep/tree touch a/'foo .ext' a/deep/'bar .otherext' a/deep/tree/'x .foo' You can find and rename all of them with rename: find a/ -name '* .*' -exec rename -v 's/ *\././' '{}' \;' resulting in: a/deep/tree/x .foo renamed as a/deep/tree/x.foo a/deep/bar .otherext renamed as a/deep/bar.otherext a/foo .ext renamed as a/foo.ext – hmontoliu Apr 28 '11 at 20:40
1  
@hmontoliu I see what you did there. Neat approach! :) – BMDan Apr 28 '11 at 22:37
show 1 more comment
feedback

This should do it for you.

#!/bin/bash

OLDIFS=${IFS}
IFS=$'\n'

for file in `find * -type f -name '* .*'`; do
 _ext=`echo ${file} | cut -d '.' -f 2-`
 _filename=`echo ${file} | cut -d ' ' -f 1`
 mv "${file}" ${_filename}.${_ext}
done

IFS=${OLDIFS}
link|improve this answer
Thanks for your answer. However the cut command didn't find the extension correctly when there were other spaces or dots in the filename. But thanks for responding. – Rich Apr 28 '11 at 3:26
No problem, glad you found a solution though. His is definitely more elegant than mine. – rfelsburg Apr 28 '11 at 3:36
feedback

I see that you've already solved your immediate problem, but in the future you might want to consider using mmv.

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

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