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

时间:2012-05-09 16:54:57

标签: bash shell variables

我一直在寻找解决方案并找到类似的问题,只是他们试图在他们之间用空格分割句子,而答案对我的情况不起作用。

目前,变量被设置为类似这样的字符串:
ABCDE-123456
我想把它分成2个变量,同时消除“ - ”。即:
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.

6 个答案:

答案 0 :(得分:163)

带有read

IFS非常适合:

$ IFS=- read var1 var2 <<< ABCDE-123456
$ echo "$var1"
ABCDE
$ echo "$var2"
123456

修改

以下是如何将每个字符读入数组元素:

$ read -a foo <<<"$(echo "ABCDE-123456" | sed 's/./& /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")'

如果字符串中有空格:

$ 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 :(得分:138)

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

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

这是做什么的? ${STR%-*}删除从字符串末尾开始匹配模式$STR的{​​{1}}的最短子字符串。 -*执行相同操作,但使用${STR#*-}模式并从字符串的开头开始。它们各自都有对等*-%%,它们会找到最长的锚定模式匹配。如果有人有一个有用的助记符来记住哪个做了哪个,请告诉我!我总是要两个都记住。

答案 2 :(得分:128)

如果你的解决方案不一定是通用的,即只需要像你的例子一样工作,你就可以这样做:

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

我在这里选择了cut,因为你可以简单地扩展代码以获得更多变量......

答案 3 :(得分:35)

听起来像是set的自定义IFS的作业。

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

(您需要在local IFS的函数中执行此操作,这样您就不会弄乱脚本中需要IFS成为您期望的其他部分。)

答案 4 :(得分:22)

使用bash正则表达式功能:

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

<强>输出

ABCDE
123456

答案 5 :(得分:16)

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