Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash string to array with IFS

I'm having trouble using the IFS to convert my string into an array. Here is what I have as my string:

"Jun01 Jun02 Jun03 Jun04 Jun05 ..." #in that format, separated by spaces

And here is the code I have tried:

IFS=" " #set it to space character
DATES_ARRAY=($DATES_STRING) #from above
echo ${DATES_ARRAY[0]} #output is empty

However when I remove the IFS line it works. But I used a few lines to print out its default ASCII value and I got '32' which means 'Space' character. Being an OCD programmer I'd like to set it myself just to be safe... I don't know how it's going to be preset a priori!

So why does trying to set IFS to Space manually not work?

like image 842
JDS Avatar asked Jul 10 '12 17:07

JDS


People also ask

How do you split a string into an array in Unix?

The delimiter “IFS” contains “space” as its value. This means the string will split into an array using the space between its values. Now, the “for” loop is used here to iterate the string “str”. Within the “do” clause, each element of an “str” variable will be displayed as an array.

How do I split a string on a delimiter in bash?

In bash, a string can also be divided without using $IFS variable. The 'readarray' command with -d option is used to split the string data. The -d option is applied to define the separator character in the command like $IFS. Moreover, the bash loop is used to print the string in split form.

How does IFS work in bash?

The meaning of IFS in Bash The IFS is a special shell variable. You can change the value of IFS as per your requirments. The Internal Field Separator (IFS) that is used for word splitting after expansion and to split lines into words with the read builtin command.


1 Answers

It does work, but it's unnecessary anyway because space is guaranteed to be in IFS by default. Don't set it manually. Doing so can cause problems.

Basically, never use word-splitting in Bash. Sometimes it's required to bite the bullet and use it if restricted to POSIX sh, if used very carefully. If you're going to set IFS, set it in the environment of one of the few commands where it has some effect, or at the very most, locally to a function.

You'll never need to use this so I won't explain everything:

$ printf -v str '%s ' Jun{01..10}
$ set -f
$ IFS=' ' declare -a 'arr=($str)'
$ declare -p arr
declare -a arr='([0]="Jun01" [1]="Jun02" [2]="Jun03" [3]="Jun04" [4]="Jun05" [5]="Jun06" [6]="Jun07" [7]="Jun08" [8]="Jun09" [9]="Jun10")'

IFS set to space here redundantly to show it works.

Probably the most correct way to go from a string to an array is to use read. Many examples here.

The cannonical method is:

read -ra arr <<<"$str"

where IFS is optionally set in the environment of read to act as a delimiter if it's something other than whitespace.

like image 199
ormaaj Avatar answered Oct 30 '22 16:10

ormaaj