Word splitting using multiple IFS

2.6k views Asked by At

Being new to shell scripting, I am not clear about the Quoting and splitting concepts in bash. In the below snippet:

array1=("france-country":"Italy-country":"singapore-country")
echo ${#array1[@]}

IFS=":-"

for i in ${array1[@]}
do
       echo "$i"
done
unset IFS

with IFS being :-, I thought the result would be:

france-country
Italy-country
belgium-country

as I had quoted them("france-country"). I think it should not get split on "-". But the results were:

france
country
Italy
country
belgium
country

It would be great if someone can point me out my mistake in understanding.

2

There are 2 answers

0
RBH On

For your problem you can simply change the field separator as : i.e. IFS=: because each country name is separated by : not :- in your example

array1=("france-country":"Italy-country":"singapore-country")
echo ${#array1[@]}

IFS=":"

for i in ${array1[@]}
do
       echo "$i"
done
unset IFS

FYI, array elements in bash are separated by space so the whole string "france-country":"Italy-country":"singapore-country" is a single element of the array therefore echo ${#array1[@]} will always be 1 . So I do not see any use of an array in this example. Simple variable would have been suffice.

0
PM 2Ring On

This script shows how to split a colon-separated string into a Bash array.

#!/usr/bin/env bash

words="france-country:Italy-country:singapore-country:Australia-country"

IFS=':' array1=($words)
numwords="${#array1[@]}"

for((i=0; i<numwords; i++));do
    echo "$i: ${array1[i]}"
done

output

0: france-country
1: Italy-country
2: singapore-country
3: Australia-country

Note that in

array1=($words)

we don't put quotes around $words, as that would prevent word splitting.

We don't actually need the quotes in

words="france-country:Italy-country:singapore-country:Australia-country"

but quotes (either single or double) would be needed if there were any spaces in that string. Similarly, the quotes are superfluous in numwords="${#array1[@]}", and many Bash programmers would omit them because we know the result of ${#array1[@]} will never have spaces in it.

It's a Good Idea to always use quotes in Bash unless you're sure you don't want them, eg in the case of array1=($words) above, or when performing tests with the [[ ... ]] syntax.

I suggest you bookmark BashGuide and browse through their FAQ. But the only way to really learn the arcane ways of quoting and splitting in Bash is to to write lots of scripts. :)

You may also find ShellCheck helpful.