The reason this is happening is because you have a file or subdirectory named C in the directory where you are running the command and so the glob ? is expanded to match it. To illustrate with a simpler example:
$ ls -la
total 92
drwxr-xr-x 2 terdon terdon 16384 Mar 26 18:53 .
drwxr-xr-x 170 terdon terdon 73728 Mar 26 13:57 ..
$ array=( $( printf '?\n' ) )
$ printf '%s\n' "${array[@]}"
?
Now, I create a file named C and try again:
$ touch C
$ array=( $( printf '?\n' ) )
$ printf '%s\n' "${array[@]}"
C
This is down to the order of operations. When you run array=( $( printf '?\n' ) ), what happens, in order, is:
- The
printf '?\n' is executed and returns a ?.
- The unquoted
? is expanded by the shell to any matching file names, in this case one called C.
- The expanded glob, the
C, is stored as element 0 of the array array.
To avoid this, you need to quote the array assignment so that any globbing characters are protected from the shell:
$ array=( "$( printf '?\n' )" )
$ printf '%s\n' "${array[@]}"
?
Or, with your original example:
$ array=( "$(grep -o -E '/ |:|\\|<|>|\*|\?|\"| $' <<< '/home/ttwaro/temp/Test/This is a Test: Testing Number 1?/This is Test: Testing Number 1?.eng.srt')" )
$ printf '%s\n' "${array[@]}"
:
?
:
?
However, because it is quoted, the entire result is presented as a single string and so the array will only have one element:
$ for ((i=0;i<${#array[@]}; i++)); do
printf 'element %s is %s\n' "$i" "${array[i]}";
done
element 0 is :
?
:
?
To get each result as a separate element in the array, you need to do something like this as suggested by Gordon Davisson in the comments:
$ readarray -t array < <(grep -o -E '/ |:|\\|<|>|\*|\?|\"| $' <<< '/home/ttwaro/temp/Test/This is a Test: Testing Number 1?/This is Test: Testing Number 1?.eng.srt')
$ for ((i=0;i<${#array[@]}; i++)); do
printf 'element %s is %s\n' "$i" "${array[i]}";
done
element 0 is :
element 1 is ?
element 2 is :
element 3 is ?
This will circumvent the need for quoting since the output of grep is never seen by the shell.
Finally, the reason you got two Cs in your result is because each of the ? was expanded to a C when it was stored in the array:
$ array=( ? ? ? )
$ printf '%s\n' "${array[@]}"
C
C
C
Cin the current directory, that is matched by the unquoted?glob perhaps??on the first line then:and then?; I don't get the first ':", but no 'C's either.Cwhich is why they seeC.array+=(? : ?)which is globbing to the single character file. The reason I don't get the first:is that the OP is using a different string after the<<<in the two examples, which is confusing.