0

I have long used code similar to :

string="abc 123 xyz"
fields=( ${string} )
echo "The 3rd field = ${fields[2]}"

to break a string into fields and reference a particular element within the string.

But I ran into a strange use case today where the source string contained an '*' asterisks character. ie:

string="abc * xyz"
fields=( ${string} )
echo "The 3rd field = ${fields[2]}"
declare -p fields

In this case, the '*' does not map into the array literally, rather it appears to get expanded to a list of environment variables, and the array ends up with a much larger list or values that do not represent the original string.

Three questions:

  1. What exactly is * being expanded to?
  2. Can this expansion be disabled so the code will behave in the intended fashion?
  3. Is there a better way to accomplish the transformation of a string into an array of tokens that do not suffer from this side effect?
0

2 Answers 2

2

Let read do it; unquoted parameter expansions are subject to pathname expansion as well as word splitting, so * is expanded to all file names in the current working directory.

read -a fields <<< "$string"

Alternatively, pathname expansion can also be disabled, allowing

set -f
fields=( $string )
set +f
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. This is the info I was looking for.
0
    • is expanded to all the files in current dir, same as ls *
  1. Use single quote. {string="abc '*' xyz"}
  2. Maybe, but this is the good way :-)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.