Terdon's Example 3 from https://unix.stackexchange.com/a/612718/182280:
Select all files except those whose names end in
.sh
or.jkl
$ shopt -s extglob nullglob $ files=(!(*.sh|*.jkl)) $ echo "${files[@]}" file.abc file.ABC file.def file.ghi
The challenge is a space in the file causes failures in the script:
for f in ${files[*]} #https://unix.stackexchange.com/q/278502/182280
do
echo "Processing $f file... "
done
For example, the space in the file fi le1.jkl
"breaks" the file when processed by the script and returns:
processing `fi` file...
processing `le1.jkl` file...
What can be done to ensure that spaces do not "break" the file name?
Comments that serve to clarify the context / questions are appreciated.
1 Answer 1
See the comment on the question the loop came from: you should use "${files[@]}"
instead of ${files[*]}
. This will ensure that each entry in the array is quoted correctly, and processed as a whole by for
:
for f in "${files[@]}"
do
echo "Processing $f file... "
done
See the Bash manual section on arrays for details:
Any element of an array may be referenced using
${name[subscript]}
. The braces are required to avoid conflicts with the shell’s filename expansion operators. If the subscript is ‘@
’ or ‘*
’, the word expands to all members of the array name. These subscripts differ only when the word appears within double quotes. If the word is double-quoted,${name[*]}
expands to a single word with the value of each array member separated by the first character of theIFS
variable, and${name[@]}
expands each element of name to a separate word.