1

I'm trying to split a string into an array using a delimiter other than space, keeping spaces preserved.

For example, if I run:

files=$(echo "foo.txt:bar.txt:my story.txt" | tr ":" "\n")
for f in $files; do
    echo $f
done

I get:

foo.txt
bar.txt
my
story.txt

How can I preserve the spaces?

3
  • I believe that the spaces are preserved in the above code. Test it again. Commented Jan 4, 2018 at 23:04
  • @VenkateshMarepalli It split my story.txt into my and story.txt Commented Jan 4, 2018 at 23:07
  • @VenkateshMarepalli, why would you expect spaces to be preserved? The unquoted expansion is subject to string splitting. See the output from ideone's online interpreter at ideone.com/kTj9A7 Commented Jan 4, 2018 at 23:10

2 Answers 2

7

files=$(cmd) is not an array assignment. It's a string assignment (the output of cmd is assigned to a regular variable files).

I would recommend using read -a to split the string as globs won't be an issue:

IFS=: read -ra files <<< "foo.txt:bar.txt:my story.txt"

for f in "${files[@]}"; do
    echo "$f"
done
Sign up to request clarification or add additional context in comments.

Comments

2

Use IFS to specify the field separator:

IFS=: files=($(echo "foo.txt:bar.txt:my story.txt"))
for f in "${files[@]}"; do
    echo "$f"
done

You also need to put parentheses around the value to make an array. You just set $files to a string where the : were replaced with newline. When you then expand $files, word splitting uses any form of whitespace, so spaces and newlines are field separators.

3 Comments

Need to disable globbing for this to be safe.
Also note that IFS will be changed.
It will not be changed. It's specified as a variable only for a specific command execution. You can try it out: IFS=: files=($(echo "foo.txt:bar.txt:my story.txt")); echo ${IFS}; echo ${files[2]} To me this is a very good answer.

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.