Work the Shell - Dealing with Spaces in Filenames

How do you deal with this problem in your scripts?

and reversed with:

original="$(echo $safename | sed s'/_-_/ /g')"

It solves the problem, but it's definitely not a very efficient or smart use of computing resources.

I've outlined three possible solution paths herein: modifying the IFS value, ensuring that you always quote filenames where referenced, and rewriting filenames internally to replace spaces with unlikely character sequences, reversing it on your way out of the script.

By the way, have you ever tried using the find|xargs pair with filenames that have spaces? It's sufficiently complicated that modern versions of these two commands have special arguments to denote that spaces might appear as part of the filenames: find -print and xargs -0 (and typically, they're not the same flags, but that's another story).

During the years I've been writing this column, I've more than once tripped up on this particular problem and received e-mail messages from readers sharing how a sample script tosses up its bits when a file with a space in its name appears. They're right.

My defensive reaction is “dude, don't use spaces in filenames”, but that's not really a good long-term solution, is it?

What I'd like to do instead is open this up for discussion on the Linux Journal discussion boards: how do you solve this problem within your scripts? Or, do you just religiously avoid using spaces in your filenames?

Dave Taylor has been hacking shell scripts for a really long time, 30 years. He's the author of the popular Wicked Cool Shell Scripts and can be found on Twitter as @DaveTaylor and more generally at


Dave Taylor has been hacking shell scripts for over thirty years. Really. He's the author of the popular "Wicked Cool Shell Scripts" and can be found on Twitter as @DaveTaylor and more generally at


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Why not using the IFS??

Saladin's picture

I've gone through this dilemma in recent project and found using IFS simple and very effective,

Is this possible for all cases and the one mentioned in the article above?


IFS=$(echo -en "\n\b")

#do what ever you want ... then restore the original variable



Salah Aldeen


The problem, internal shell conversions

xae's picture

To manage this problem I had been using code like this,

for filename in *; do aux=$filename/; LS[${#LS[@]}]=${aux%/}; done
rm "${LS[24]}", as example

The catch here is to avoid the conversions taken by the shell when you access to the content of a variable, the trick is to append to the variable a character, trying to make the shell guess that it's a string, and then you can gain access without infamous conversions, but at later you ougth to remove the char in order to use it as a filename.

The chars candidates for this job are NUll, $'/0, and "/".

s/find -print/find -print0/ ?

mattcen's picture

Dave, did you mean '-print0' as opposed to '-print'? While both kind of make sense, when paired with 'xargs -0' I think the former makes *more* sense.

With respect to spaces, I usually don't bother dealing with them unless I *know* that they'll be there (e.g. I'm manipulating data that non-geek customers access via a Samba share and put plenty of weird characters in).

One of the other solutions I've considered, but not really had to use yet, is to switch to Perl or Python for these particular use-cases, given they handle escaping of spaces somewhat better.

It's something I'd rather not do given I'm more familiar with Bash than either of the above, but it may be the lease bad solution, even if I do have to dig up my text books to work out how to do something that would be trivial in Bash.

Matthew Cengia