Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

This question already has an answer here:

I have quite a number of files and directories with spaces in their filenames in my ext4 filesystems.

How should I safely find and rename them? I have bash and am running Ubuntu.

Is it possible to interactively rename each found file, i.e. be asked if I want to rename what to what for each file?

What convention for choosing filenames would you use to rename them?

share|improve this question

marked as duplicate by Rui F Ribeiro, garethTheRed, roaima, Jakuje, cuonglm Feb 28 at 10:59

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
Since you ask "what convention…would you use", this suggests that having spaces is not a convention? What is the problem with spaces in filenames? (Can you not just escape/quote properly?) – Sparhawk Feb 28 at 0:03
    
Spaces in filenames make find and xargs more complicated. – Tim Feb 28 at 0:04
    
Yes, but this you can get around this by quoting and escaping correctly. Anyway, a partial answer is find -name '* *' -execdir sh -c 'mv -i "$1" "$(<<<$1 sed "s/ /_/g")"' _ {} \;, but the -i argument to mv isn't working in the script, so it's not interactive. I guess you could just use a more complicated read conditional. – Sparhawk Feb 28 at 0:09
    
Oh I got confused. -i is only interactive if it's overwriting. Is that what you want, or do you want to be interactive in all cases? – Sparhawk Feb 28 at 0:17
    
Thanks. in all cases. – Tim Feb 28 at 0:18

This script will find all files in a target directory, and generate a new script that will rename all of the files to not have spaces. You can then review the script at your leisure before execution:

#!/bin/bash
TARGET=/path/to/files
NEWSCRIPT=${HOME}/rename-spaced-files.sh

OLDIFS="${IFS}"
IFS="\n"
for file in $(find ${TARGET}/ -type f -name "* *"); do
    if [[ -f \"${file// /}\" ]]; then
        echo "# \"${file// /}\" already exists- come up with a new name for it and uncomment the next line" >> $NEWSCRIPT
        echo -n "# " >> $NEWSCRIPT
    fi
    echo "mv \"${file}\" \"${file// /}\"" >> $NEWSCRIPT

done
share|improve this answer
2  
It'd be great to add a -f test around the echo/mv; if the no-space version of a file already exists, emit a warning instead of an overwriting mv command. Then the user can manually rename. – Jeff Schaller Feb 28 at 2:10
    
Good idea. Done- now it will put a warning and a commented-out mv in the generated script. – DopeGhoti Feb 28 at 2:47
    
The following test incorrectly adds double quotes to the filename: [[ -f \"${file// /}\" ]]. Not only do the quotes not require backslash escaping, since the [[ construct performs neither field splitting nor pathname expansion, they do not need to be present at all. – Barefoot IO Feb 28 at 4:10
    
Testing with sprunge.us/VPDG shows that you're incorrect about quotes being added to filenames. – DopeGhoti Feb 28 at 17:44

Per directory, using rename is easy:

rename 's/\s/_/g' *

That will get rid of all spaces in file names in the directory and replace them with '_'. If you leave off the 'g' it would only replace the first space in the file name, so don't forget that part. * means all the files in the directory you run it in.

rename 's/\s/_/g' /home/you/something/*

Would replace all spaces in file names in the directory: /home/you/something/

This doesn't cover going through many directories, but that's how I'd do it in general.

I like underscores, that would change:

my file with spaces.txt

to

my_file_with_spaces.txt
share|improve this answer

While having spaces in filenames is totally legit in Unix and its file systems, you have to take care that you quote the names when using them with shell commands or from variables, e. g. in scripts. Else the shell will pass each word as a separate parameter to the command.

VAR="existing file with spaces in name"

#This works
ls "${VAR}"

#This results in file(s) not found
ls ${VAR}

Additionally to the answers already given, you could also use the mmv command to rename multiple files whose names match a pattern, independent from spaces in the names because with mmv you have to quote the source and target pattern anyhow.

And shamelessly quoting myself (pun not intended but merrily accepted):

Rule of thumb: Always use quotes around shell variables that contain strings when expanding them; they may contain spaces or be empty, which when unquoted often confuses the command they're passed to (too many or missing parameters).

share|improve this answer

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