STOP: WP_HEAD -->

How to Remove Spaces from Filenames in Linux/UNIX

This command will rename all files that have spaces in their filenames, in the current directory and recursively in its subdirectories, so that in the new filenames all spaces are replaced with underscores (‘_’ characters).

find . -name '* *' | while read file;
do
target=`echo "$file" | sed 's/ /_/g'`;
echo "Renaming '$file' to '$target'";
mv "$file" "$target";
done;

I tested the command with BASH, but it should work with most shells.

How it works

In case you’re interested in how the command works, here is a quick explanation.

1. We use the ‘find’ command to get a list of all files with spaces in their filenames, from the current directory:

find . -name '* *'

2. We ‘pipe’ the list of filenames to a while loop, that will individually process each filename, by reading it into an environmental variable called ‘file’.

while read file;
do
...
done;

3. Inside the while loop, we firstly work out what the new filename should be, by using ‘sed’ to replace all spaces with underscores in the filename, then we print a message to the console using ‘echo’ and then finally, we rename the file using ‘mv’.

target=`echo "$file" | sed 's/ /_/g'`;
echo "Renaming '$file' to '$target'";
mv "$file" "$target";

Tags: , , , ,

  1. Justin

    Thanks for the script, funny how it took me almost an hour on google to find this, “replace spaces in filename for all files in directory”.

  2. MvE

    Nice. It is possible to string this all together in one line, of course.

  3. Conor

    This does not work if you’re trying to remove whitespace from directories (and their subdirectories!) as well as all files. The logic in the code posted works so that directories are renamed recursively, and the paths to the files in subdirectories are not rewritten accordingly, so the deeply nested files are not renamed. You will have to rerun this code one additional time per each additional level of depth you have in your directory tree.

    For one-shot solution in Perl, try here: http://www.perlmonks.org/?node_id=27739

  4. Phil

    Thanks for the code and nice explanation — always appreciate the latter. Just starting to understand the power of sed.

  5. grace

    Hello,
    Thank you very much.
    I wanted to remove () from file name..
    and your script worked gr8
    Keep up the godd work
    best regards

  6. Tiago Hillebrandt

    Another way: rename “s/ *//g” *

  7. Tiago Hillebrandt

    PS: Doesn’t works recursively.

  8. Nikhil

    Worked awesome, thanks! And yes, it worked recursively.

  9. Susanna Kaukinen

    There’s a tool for this => http://linux.die.net/man/1/detox

  10. Michael Byrne

    Lovely loop, Many thanks.

  11. Santhosh

    Good simple code.. easy to understand. Thanks

  12. Zeh Ferrari

    It couldn’t be simpler! Thank you for sharing!

  13. hlosukwakha

    The script is great. However, you have to be aware that if there are subdirectories the script first changes the subdirectories names and then gives errors when it tries to rename the files inside the directories. I ignored the errors and ran the script a second time and it worked perfectly changing the names of the files in the subdirectories.

  14. Jadi

    Tnx. helped me :)

  15. Esteban

    Thanks! I was looking for a command that works recursively. I searched all evening before finding this page. Of course this is more of comment of my lack of search ability.

  16. sheetal suryan

    thanks,

  17. drearick

    thanks a lot, it’s very helpful and the structure is easy to adapt.

  18. Simple and Nice script

    Nice

  19. mark

    Does not work for renaming files in directories that contain whitespaces
    e.g.
    my dir/my file
    directory is renamed to
    my_dir
    but the list of filenames stays the same for the whole loop
    therefore cannot find
    my dir/my file (beacues path is now my_dir/my file)
    In this case either run multiple times or to extra loop
    for level in 1 2 3 4 5 6 7 8 9 10 11 12 #as many levels as you need
    do
    find . -maxdepth $level -name ‘* *’ | while read file;
    do
    target=`echo “$file” | sed ‘s/ /_/g’`;
    echo “Renaming ‘$file’ to ‘$target’”;
    mv “$file” “$target”;
    done;
    done;

    For large directories the maxdepth option prevents running multiple times over the whole tree

Add a Comment