Construct Array from String seperated by different whitespaces

My string variable which gets the output from the result of a database query has values as below:

line="2019-09-11 15:17:55 CR1234 anonymous       Deployed        DR_only        Back_APP"

I wish to construct an array (my_array) which should have entries as below.

Note:

  1. The first two strings seperated by whitespace combines to be the first element of the array.
  2. Not all white spaces between the strings are the same.

Below code code does not split all the elements of the string as desired.

      IFS=$' ' read -ra my_array <<< "$line"
      #Print the split string
      for i in "${my_array[@]}"
      do
         echo $i
      done

Can you please propose a viable solution ?

I m on Redhat Linux centos 7 using bash.

Hi,

I have done the following to your code;

IFS=$' ' read -ra my_array <<< "Filesystem            kbytes    used   avail capacity  Mounted on"
#Print the split string
for i in "${my_array[@]}"
do
     echo $i
done

And get the following result;

-bash-3.2$ ./arrtest.sh
Filesystem
kbytes
used
avail
capacity
Mounted
on
-bash-3.2$

Can you post your output? Could there be any non printing characters in the sql output - well other than a tab?

Regards

Gull04

I tried your suggestion and it does not yeild any output. However, the tr command helps reconstruct the variable to have a single space only.

The challenge remains of how to get the first two words seperated by single space get stored as first array element and then the rest of the words as subsiquent array elements.

$ IFS=$' ' read -ra my_array <<<"2019-09-11 15:17:55 CR1234 anonymous       Deployed        DR_only        Back_APP" 
$ echo $?
0
$ echo "2019-09-11 15:17:55 CR1234 anonymous       Deployed        DR_only        Back_APP" |  tr -s " "
2019-09-11 15:17:55 CR1234 anonymous Deployed DR_only Back_APP

Hi Motashims,

I've tried this on a couple of systems and get the following - for Solaris;

-bash-3.2$ cat arrtest.sh
IFS=' ' read -ra my_array <<< "2019-09-11 15:17:55 CR1234 anonymous       Deployed        DR_only        Back_APP"
#Print the split string
for i in "${my_array[@]}"
do
     echo $i
done
-bash-3.2$ ./arrtest.sh
2019-09-11
15:17:55
CR1234
anonymous
Deployed
DR_only
Back_APP
-bash-3.2$ uname -a
SunOS isd250 5.10 Generic_150400-46 sun4v sparc sun4v
-bash-3.2$ bash --version
GNU bash, version 3.2.52(1)-release (sparc-sun-solaris2.10)
Copyright (C) 2007 Free Software Foundation, Inc.
-bash-3.2$

And on a much later version of Red Hat;

[root@fbakirpomd4 bin]# cat arrtest.sh
IFS=' ' read -ra my_array <<< "2019-09-11 15:17:55 CR1234 anonymous       Deployed        DR_only        Back_APP"
#Print the split string
for i in "${my_array[@]}"
do
     echo $i
done
[root@fbakirpomd4 bin]# ./arrtest.sh
2019-09-11
15:17:55
CR1234
anonymous
Deployed
DR_only
Back_APP
[root@fbakirpomd4 bin]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.5 (Maipo)
[root@fbakirpomd4 bin]# bash --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[root@fbakirpomd4 bin]#

I'm unable to replicate the issue - I think.

Regards

Gull04

Can you share the logic / code to add first two elements seperated by single space to array[0] and the next elements thereon ?

Hi Motashims,

I have shared everything with you, can I ask what output are you expecting?

Am I right in assuming that you expect different output from above, maybe.

2019-09-11 15:17:55
CR1234
anonymous
Deployed
DR_only
Back_APP

Regards

Gull04

--- Post updated at 01:35 PM ---

Hi Motashims,

Is the following what you expect?

-bash-3.2$ cat -v -t arrtest.sh
IFS='^I' read -ra my_array <<< "2019-09-11 15:17:55^ICR1234^Ianonymous^IDeployed^IDR_only^IBack_APP"
#Print the split string
for i in "${my_array[@]}"
do
     echo $i
done
-bash-3.2$ ./arrtest.sh
2019-09-11 15:17:55
CR1234
anonymous
Deployed
DR_only
Back_APP
-bash-3.2$

Here you have to explicitly set the IFS to the tab character, this will ignore the space.

Regards

Gull04

--- Post updated at 01:35 PM ---

Hi Motashims,

Is the following what you expect?

-bash-3.2$ cat -v -t arrtest.sh
IFS='^I' read -ra my_array <<< "2019-09-11 15:17:55^ICR1234^Ianonymous^IDeployed^IDR_only^IBack_APP"
#Print the split string
for i in "${my_array[@]}"
do
     echo $i
done
-bash-3.2$ ./arrtest.sh
2019-09-11 15:17:55
CR1234
anonymous
Deployed
DR_only
Back_APP
-bash-3.2$

Here you have to explicitly set the IFS to the tab character, this will ignore the space.

Regards

Gull04

1 Like

You could use a function to extract the required elements like this:

function splitarr {
    local pos=0 word=0 items value i
    local wrd=( $1 )
    for items in $3
    do
       value=""
       for((i=0;i<$items;i++))
       do
          [ $i -gt 0 ] && value="$value "
          value="$value${wrd[$word]}"
          (( word++ ))
       done
       printf -v $2[$pos] "%s" "$value"
       (( pos++ ))
    done
}

line="2019-09-11 15:17:55 CR1234 anonymous Deployed     DR_only Back_APP"
splitarrr "$line" my_array "2 1 1 1 1 1"
for((i=0;i<${#my_array[@]};i++))
do
    echo "my_array[$i]=${my_array}"
done

Output:

my_array[0]=2019-09-11 15:17:55
my_array[1]=CR1234
my_array[2]=anonymous
my_array[3]=Deployed
my_array[4]=DR_only
my_array[5]=Back_APP
1 Like
Moderator comments were removed during original forum migration.

For reference, in bash (gitbash in my case) this works nicely for taking a string (called $theline in this example) with a number of words that are separated by a space. I'm using two words, but it would work with many more. e.g. "word1 word2"
The words are parsed into an array, called "strings".

read -a strings <<< "$theline"
echo "There are ${#strings[*]} words."
for val in "${strings[@]}"; do
	printf "$val\n"
done
word1=${strings[0]}
word2=${strings[1]}

...
Hope this helps.

1 Like