Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Bash and IFS: string split to an array with specific separator add an extra empty element

About split a string into an array we have two scenarios:

if the string has empty spaces how a separator, according with the following post:

So If I use:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

string="Hello Unix World"
array1=($string)
echo ${array1[@]}
echo "size: '${#array1[@]}'"

read -a array2 <<< $string
echo ${array2[@]}
echo "size: '${#array2[@]}'"

The output is:

Hello Unix World
size: '3'
Hello Unix World
size: '3'

Both approaches works as expected.

Now, if the string has something different than an empty space how a separator, according with the following post:

So If I use:

path="/home/human/scripts"
IFS='/' read -r -a array <<< "$path"

echo "Approach 1"
echo ${array[@]}
echo "size: '${#array[@]}'"

echo "Approach 2"
for i in "${array[@]}"; do
   echo "$i"
done

echo "Approach 3"
for (( i=0; i < ${#array[@]}; ++i )); do
    echo "$i: ${array[$i]}"
done

It prints:

Approach 1
home human scripts    <--- apparently all is ok, but see the line just below!
size: '4'
Approach 2
                      <--- an empty element
home
human
scripts
Approach 3
0:                    <--- confirmed, the empty element
1: home
2: human
3: scripts

Why appears that empty element? How fix the command to avoid this situation?

>Solution :

Your string split into 4 parts: an empty one, and the three words.

path="/home/human/scripts"
IFS='/' read -r -a array <<< "$path"
declare -p array

Output:

declare -a array=([0]="" [1]="home" [2]="human" [3]="scripts")

There are many ways to fix it. One is to delete the empty values. Another is to exclude the beginning slash before splitting.

for i in "${!array[@]}"; do
    [[ ${array[i]} ]] || unset 'array[i]'
done

Or

IFS='/' read -r -a array <<< "${path#/}"

The first one is adaptable to path forms were slashes are repeated not only in the beginning.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading