Splitting string into array
I want to split the string and construct the array. I tried the below code:
myString="first column:second column:third column"
set -A myArray `echo $myString | awk 'BEGIN{FS=":"}{for (i=1; i<=NF; i++) print $i}'`
# Following is just to make sure that array is constructed properly
i=0
while [ $i -lt ${#myArray[@]} ]
do
echo "Element $i:${myArray[$i]}"
(( i=i+1 ))
done
exit 0
It produces the following result:
Element 0:first
Element 1:column
Element 2:second
Element 3:column
Element 4:third
Element 5:column
This is not what I want it to be. When I construct the array, I want that array 开发者_StackOverflow社区to contain only three elements.
Element 0:first column
Element 1:second column
Element 2:third column
Can you please advise?
Here is how I would approach this problem: use the IFS variable to tell the shell (bash) that you want to split the string into colon-separated tokens.
$ cat split.sh
#!/bin/sh
# Script to split fields into tokens
# Here is the string where tokens separated by colons
s="first column:second column:third column"
IFS=":" # Set the field separator
set $s # Breaks the string into $1, $2, ...
i=0
for item # A for loop by default loop through $1, $2, ...
do
echo "Element $i: $item"
((i++))
done
Run it:
$ ./split.sh
Element 0: first column
Element 1: second column
Element 2: third column
if you definitely want to use arrays in Bash, you can try this way
$ myString="first column:second column:third column"
$ myString="${myString//:/ }" #remove all the colons
$ echo "${myString}"
first column second column third column
$ read -a myArr <<<$myString
$ echo ${myArr[@]}
first column second column third column
$ echo ${myArr[1]}
column
$ echo ${myArr[2]}
second
otherwise, the "better" method is to use awk entirely
Note that saving and restoring IFS as I often seen in these solutions has the side effect that if IFS wasn't set, it ends up changed to being an empty string which causes weird problems with subsequent splitting.
Here's the solution I came up with based on Anton Olsen's extended to handle >2 values separated by a colon. It handles values in the list that have spaces correctly, not splitting on the space.
colon_list=${1} # colon-separate list to split
while true ; do
part=${colon_list%%:*} # Delete longest substring match from back
colon_list=${colon_list#*:} # Delete shortest substring match from front
parts[i++]=$part
# We are done when there is no more colon
if test "$colon_list" = "$part" ; then
break
fi
done
# Show we've split the list
for part in "${parts[@]}"; do
echo $part
done
Ksh or Bash
#! /bin/sh
myString="first column:second column:third column"
IFS=: A=( $myString )
echo ${A[0]}
echo ${A[1]}
Looks like you've already found the solution, but note that you can do away with awk entirely:
myString="first column:second column:third column"
OIFS="$IFS"
IFS=':'
myArray=($myString)
IFS=$OIFS
i=0
while [ $i -lt ${#myArray[@]} ]
do
echo "Element $i:${myArray[$i]}"
(( i=i+1 ))
done
精彩评论