如何在bash shell中将一个字符串分割成多个变量?

 2019-05-06 

How to split one string into multiple variables in bash shell?

本问题已经有最佳答案,请猛点这里访问。

我一直在寻找解决方案,发现了类似的问题,只是他们试图用空格分割句子,答案不适合我的情况。

当前正在将一个变量设置为如下字符串:
ABCDE-123456
我想把它分成两个变量,同时去掉"-"。即:
var1=ABCDE
var2=123456

怎样才能做到这一点?

这是对我有效的解决方案:
var1=$(echo $STR | cut -f1 -d-)
var2=$(echo $STR | cut -f2 -d-)

是否可以使用不带分隔符的CUT命令(每个字符都被设置为变量)?

var1=$(echo $STR | cut -f1 -d?)
var2=$(echo $STR | cut -f1 -d?)
var3=$(echo $STR | cut -f1 -d?)
etc.


readIFS是完美的:

1
2
3
4
5
$ IFS=- read var1 var2 <<< ABCDE-123456
$ echo"$var1"
ABCDE
$ echo"$var2"
123456

编辑:

以下是如何将每个单独的字符读取到数组元素中:

1
$ read -a foo <<<"$(echo"ABCDE-123456" | sed 's/./& /g')"

转储数组:

1
2
$ 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")'

如果字符串中有空格:

1
2
3
$ 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")'


如果您知道它只是两个字段,那么可以跳过这样的额外子流程:

1
2
var1=${STR%-*}
var2=${STR#*-}

这是做什么的?${STR%-*}删除与模式-*匹配的$STR的最短子串,从字符串的末尾开始。${STR#*-}也做同样的事情,但使用*-模式,从字符串的开头开始。它们都有对应的%%##,它们找到了最长的锚定模式匹配。如果有人有一个有用的助记法来记住哪一个做的,请告诉我!我总是要努力记住这两个。


如果您的解决方案不必是一般性的,即只需要对像您的示例这样的字符串有效,则可以执行以下操作:

1
2
var1=$(echo $STR | cut -f1 -d-)
var2=$(echo $STR | cut -f2 -d-)

我在这里选择了cut,因为您可以简单地将代码扩展为更多的变量…


听上去像是一个为set定制的IFS工作。

1
2
3
4
IFS=-
set $STR
var1=$1
var2=$2

(您将希望在使用local IFS的函数中执行此操作,这样就不会把脚本中要求IFS达到预期效果的其他部分搞得一团糟。)


使用bash regex功能:

1
2
3
4
re="^([^-]+)-(.*)$"
[["ABCDE-123456" =~ $re ]] && var1="${BASH_REMATCH[1]}" && var2="${BASH_REMATCH[2]}"
echo $var1
echo $var2

产量

1
2
ABCDE
123456


1
2
3
4
5
string="ABCDE-123456"
IFS=- # use"local IFS=-" inside the function
set $string
echo $1 # >>> ABCDE
echo $2 # >>> 123456