211

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

目前,一个变量被设置为这样的字符串:
ABCDE-123456
我想将其拆分为 2 个变量,同时消除“ - ”。IE:
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.

4

5 回答 5

263

要拆分由 分隔的字符串-,您可以使用readwith 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")'
于 2012-05-10T03:14:24.343 回答
219

如果您知道它将只有两个字段,则可以跳过这样的额外子流程,使用:

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

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

有关更多信息,请参阅bash 文档

于 2012-05-09T17:02:19.263 回答
182

如果您的解决方案不必是通用的,即只需要像您的示例那样适用于字符串,您可以这样做:

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

我选择cut这里是因为您可以简单地为更多变量扩展代码......

于 2012-05-09T17:00:36.877 回答
49

听起来像set一个自定义的工作IFS

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

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

于 2012-05-09T17:57:58.760 回答
33

使用 bash 正则表达式功能:

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

输出

ABCDE
123456
于 2012-05-09T17:09:48.793 回答