How do I split a string based on a delimiter in Bash?
I have this string stored in a variable:
IN="bla@some.com;john@home.com"
Now I would like to split the strings by ';' delimiter so that I have
ADDR1="bla@some.com"
ADDR2="john@home.com"
I don't necessarily need the ADDR1
and ADDR2
variables. If they are elements of an array that's even better.
Edit : After suggestions from the answers below, I ended up with the following which is what I was after:
#!/usr/bin/env bash
IN="bla@some.com;john@home.com"
arr=$(echo $IN | tr ";" "\n")
for x in $arr
do
echo "> [$x]"
done
output:
> [bla@some.com]
> [john@home.com]
Edit2 : There was a solution involving setting Internal_field_separator (IFS) to ';'. I am not sure what happened with that answer, how do you reset IFS back to default?
Edit3 : RE: IFS solution, I tried this and it works, I keep the old IFS and then restore it:
IN="bla@some.com;john@home.com"
OIFS=$IFS
IFS=';'
arr2=$IN
for x in $arr2
do
echo "> [$x]"
done
IFS=$OIFS
BTW, when I tried
arr2=($IN)
I only got the first string when printing it in loop, without brackets around $IN
it works.
Source: Tips4all, CCNA FINAL EXAM
You can set the internal field separator (IFS) variable, and then let it parse into an array. When this happens in a command, then the assignment to IFS only takes place to that single command's environment (to read ). It then parses the input according to the IFS variable value into an array, which we can then iterate over.
ReplyDeleteIFS=';' read -ra ADDR <<< "$IN"
for i in "${ADDR[@]}"; do
# process "$i"
done
It will parse one line of items separated by ;, pushing it into an array. Stuff for processing whole of $IN, each time one line of input separated by ;:
while IFS=';' read -ra ADDR; do
for i in "${ADDR[@]}"; do
# process "$i"
done
done <<< "$IN"
If you don't mind processing them immediately, I like to do this:
ReplyDeletefor i in $(echo $IN | tr ";" "\n")
do
# process
done
You could use this kind of loop to initialize an array, but there's probably an easier way to do it. Hope this helps, though.
Taken from Bash shell script split array:
ReplyDeleteIN="bla@some.com;john@home.com"
arrIN=(${IN//;/ })
How about this approach:
ReplyDeleteIN="bla@some.com;john@home.com"
set -- "$IN"
IFS=";"; declare -a Array=($*)
echo "${Array[@]}"
echo "${Array[0]}"
echo "${Array[1]}"
Source
echo "bla@some.com;john@home.com" | sed -e 's/;/\n/g'
ReplyDeletebla@some.com
john@home.com
A different take on Darron's answer, this is how I do it:
ReplyDeleteIN="bla@some.com;john@home.com"
read ADDR1 ADDR2 <<<$(IFS=";"; echo $IN)
You may also:
ReplyDeletedirList=(
some
list
of
elements
)
for i in ${dirList[@]}; do
...
done
How about this one liner, if you're not using arrays:
ReplyDeleteIFS=';' read ADDR1 ADDR2 <<<$IN
There are two simple methods:
ReplyDeletecat "text1;text2;text3" | tr " " "\n"
and
cat "text1;text2;text3" | sed -e 's/ /\n/g'
This is the simplest way to do it.
ReplyDeletespo='one;two;three'
OIFS=$IFS
IFS=';'
spo_array=($spo)
IFS=$OIFS
echo ${spo_array[*]}