I'm trying to construct an array in bash of the filenames from my camera:
FILES=(2011-09-04 21.43.02.jpg
2011-09-05 10.23.14.jpg
2011-09-09 12.31.16.jpg
2011-09-11 08.43.12.jpg)
As you can see, there is a space in the middle of each filename.
I've tried wrapping each name in quotes, and escaping the space with a backslash, neither of which works.
When I try to access the array elements, it continues to treat the space as the elementdelimiter.
How can I properly capture the filenames with a space inside the name?
I agree with others that it's likely how you're accessing the elements that is the problem. Quoting the file names in the array assignment is correct:
Using double quotes around any array of the form
"${FILES[@]}"
splits the array into one word per array element. It doesn't do any word-splitting beyond that.Using
"${FILES[*]}"
also has a special meaning, but it joins the array elements with the first character of $IFS, resulting in one word, which is probably not what you want.Using a bare
${array[@]}
or${array[*]}
subjects the result of that expansion to further word-splitting, so you'll end up with words split on spaces (and anything else in$IFS
) instead of one word per array element.Using a C-style for loop is also fine and avoids worrying about word-splitting if you're not clear on it:
Another solution is using a "while" loop instead a "for" loop:
I think the issue might be partly with how you're accessing the elements. If I do a simple
for elem in $FILES
, I experience the same issue as you. However, if I access the array through its indices, like so, it works if I add the elements either numerically or with escapes:Any of these declarations of
$FILES
should work:or
or
If you aren't stuck on using
bash
, different handling of spaces in file names is one of the benefits of the fish shell. Consider a directory which contains two files: "a b.txt" and "b c.txt". Here's a reasonable guess at processing a list of files generated from another command withbash
, but it fails due to spaces in file names you experienced:With
fish
, the syntax is nearly identical, but the result is what you'd expect:It works differently because fish splits the output of commands on newlines, not spaces.
If you have a case where you do want to split on spaces instead of newlines,
fish
has a very readable syntax for that:Escaping works.
Output:
Quoting the strings also produces the same output.
You need to use IFS to stop space as element delimiter.
If you want to separate on basis of . then just do IFS="." Hope it helps you:)