Using a string var with carefully crafted newline-delimited substrings:
tmp1=' M file*4.bin'$'\n''AM file5\0345.txt'$'\n''M file6a$\t.rtf'
Note the concatenation via $'\n', in order to actually insert newline control chars, instead of just '\n' substrings and single-quoted substrings, to preserve special chars/avoid escaping.
The code below should work with arrays as well:
tmp2=(' M file*1.bin' 'AM file2\0345.txt' 'M file3a$\t.rtf')
Iterating the string in a for loop now can be achieved via unquoted expansion to a single string ([*]) and IFS restriction to newline (the printf variant can give more control, but invokes a subshell:
_IFS="$IFS"; IFS=$'\n' #for e in $(printf '%s\n' "${tmp1[*]}"); do for e in ${tmp1[*]}; do printf 'ELEM: [%s]\n' "$e" done IFS="$_IFS"
Note the missing double quotes around ${tmp1[*]}, in order to expand and split at the newline control chars, instead of expanding to just a single string here.
The surrounding IFS modification and reset should prevent accidential splitting at spaces or tabs, but might also affect commands inside the loop.
Also consider the hint on requiring to disable globbing from 'dave_thompson_085' below, in case the input strings may contain escaped or special chars (not single-quoted).
A while loop over a quoted expanded Here String may be the better choice, depending on the input. Narrowing the IFS to only newlines for just the loop is possible, but shouldn't be necessary:
while IFS=$'\n' read -r; do printf 'ELEM: [%s]\n' "$REPLY" done <<<"$tmp1"
When we have an array, it can be simply iterated with a for loop, from a quoted array Parameter Expansion ([@]) - note the double-quotes here:
for e in "${tmp2[@]}"; do printf 'ELEM: [%s]\n' "$e" done
or with while loop:
_IFS="$IFS"; IFS=$'\n' while read -r; do printf 'ELEM: [%s]\n' "$REPLY" done <<<"${tmp2[*]}" # done < <(printf '%s\n' "${tmp2[*]}") IFS="$_IFS" # done <<<"${tmp2[@]@E}"
The usage of @E as operator for the array Parameter Expansion ([@]), is required to expand the newline control chars, but this will also expand other special chars end escape sequences, which may be undesired.
To avoid this, restricting the IFS to newline (and restoring it) and expanding the array to a single string ([*]) is used instead.
Alternatively, the array splitting can be done via Command Substitution and printf.
This code should work for newline-delimited strings, as well as for arrays.