I've been looking for a solution and found similar questions, only they were attempting to split sentences with spaces between them, and the answers do not work for my situation.
Currently a variable is being set to something a string like this:
ABCDE-123456
and I would like to split that into 2 variables, while eliminating the "-". i.e.:
var1=ABCDE
var2=123456
How is it possible to accomplish this?
This is the solution that worked for me:
var1=$(echo $STR | cut -f1 -d-)
var2=$(echo $STR | cut -f2 -d-)
Is it possible to use the cut command that will work without a delimiter (each character gets set as a variable)?
var1=$(echo $STR | cut -f1 -d?)
var2=$(echo $STR | cut -f1 -d?)
var3=$(echo $STR | cut -f1 -d?)
etc.
If you know it's going to be just two fields, you can skip the extra subprocesses like this:
var1=${STR%-*}
var2=${STR#*-}
What does this do? ${STR%-*}
deletes the shortest substring of $STR
that matches the pattern -*
starting from the end of the string. ${STR#*-}
does the same, but with the *-
pattern and starting from the beginning of the string. They each have counterparts %%
and ##
which find the longest anchored pattern match. If anyone has a helpful mnemonic to remember which does which, let me know! I always have to try both to remember.
read
with IFS
are perfect for this:
$ IFS=- read var1 var2 <<< ABCDE-123456
$ echo "$var1"
ABCDE
$ echo "$var2"
123456
Edit:
Here is how you can read each individual character into array elements:
$ read -a foo <<<"$(echo "ABCDE-123456" | sed 's/./& /g')"
Dump the array:
$ declare -p foo
declare -a foo='([0]="A" [1]="B" [2]="C" [3]="D" [4]="E" [5]="-" [6]="1" [7]="2" [8]="3" [9]="4" [10]="5" [11]="6")'
If there are spaces in the string:
$ IFS=$'\v' read -a foo <<<"$(echo "ABCDE 123456" | sed 's/./&\v/g')"
$ declare -p foo
declare -a foo='([0]="A" [1]="B" [2]="C" [3]="D" [4]="E" [5]=" " [6]="1" [7]="2" [8]="3" [9]="4" [10]="5" [11]="6")'
Using bash regex capabilities:
re="^([^-]+)-(.*)$"
[[ "ABCDE-123456" =~ $re ]] && var1="${BASH_REMATCH[1]}" && var2="${BASH_REMATCH[2]}"
echo $var1
echo $var2
OUTPUT
ABCDE
123456
Sounds like a job for set
with a custom IFS
.
IFS=-
set $STR
var1=$1
var2=$2
(You will want to do this in a function with a local IFS
so you don't mess up other parts of your script where you require IFS
to be what you expect.)
Source: Stackoverflow.com