Escaping in Bash: how to handle multiple file names containing spaces

2 min read >

Escaping in Bash: how to handle multiple file names containing spaces

Embedded & Engineering Insights

Did you ever save file names in a bash parameter, and everything crashed down when they contain spaces?

The script started simple:

FILENAMES="log-file-1.txt log-file-2.txt"
cp $FILENAMES logs
rm $FILENAMES

When you have spaces, it becomes a nightmare. You’ll probably add a lot of quotes and try first something like this:

FILENAMES='"log file 1.txt" "log file 2.txt"'
cp $FILENAME logs
rm $FILENAME

Don’t try it at home, it does not work. Bash applies its dreadfully complex parameter expansion rules and you will end up with useless errors about things called “log”, “file” and “1.txt” which cannot be found.

Solution: use arrays:

FILENAMES=(
"log file 1.txt"
"log file 2.txt"
)
cp "${FILENAMES[@]}" logs
rm "${FILENAMES[@]}"

They work only on bash. Here’s a page about how they work.