3

I'm trying to split a string into individual characters. For example temp="hello" into "h", "e", "l", "l", "o"

I tried using IFS because that's what I used in previous string splits and wanted to keep the consistency across the script. IFS='' read h e l l o <<<"$temp" does not work. What am I doing wrong?

4
  • 2
    Blank IFS is "don't split". Commented Sep 3, 2015 at 20:15
  • @EtanReisner So is there NO absolute way to do a blank split using IFS? Commented Sep 3, 2015 at 20:18
  • There's no "split every character" trick with IFS that I'm aware of. You could probably read -n 1 -r char in a loop though. Commented Sep 3, 2015 at 20:19
  • @EtanReisner alright, thank you Commented Sep 3, 2015 at 20:19

2 Answers 2

6

You can use fold:

arr=($(fold -w1 <<< "$temp"))

Verify:

declare -p arr
declare -a arr='([0]="h" [1]="e" [2]="l" [3]="l" [4]="o")'
Sign up to request clarification or add additional context in comments.

2 Comments

Is there a way to do the same thing with IFS?
No IFS based splitting on individual character. There are many other tricks available like grep -o . <<< "$temp" or even awk
2

TL;DR: this is just to see if it can be done. Use fold like anubhava suggests; starting a single process is a small price to pay to avoid not one, but two uses of eval.


I wouldn't actually use this (I think it's safe, but I wouldn't swear to it, and boy, is it ugly!), but you can use eval, brace expansion, and substring parameter expansion to accomplish this.

$ temp=hello
$ arr=( $(eval echo $(eval echo \\\${temp:{0..${#temp}}:1})) )
$ printf '%s\n' "${arr[@]}"
h
e
l
l
o

How does this work? Very delicately. First, the shell expands ${#temp} to the length of the variable whose contents we want to split. Next, the inner eval turns the string \${temp:{0..5}:1} into a set of strings ${temp:0:1}, ${temp:1:1}, etc. The outer eval then performs the parameter expansions that produce one letter each from temp, and those letters provide the contents of the array.

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.