我将此字符串存储在变量中:

IN="bla@some.com;john@home.com"

现在,我想将字符串拆分为:;分隔符,以便我可以:

ADDR1="bla@some.com"
ADDR2="john@home.com"

我不一定需要ADDR1和ADDR2变量。如果它们是数组的元素,那就更好了。


根据以下答案的建议,我最终得出了以下结论,这就是我想要的:

#!/usr/bin/env bash

IN="bla@some.com;john@home.com"

mails=$(echo $IN | tr ";" "\n")

for addr in $mails
do
    echo "> [$addr]"
done

输出:

> [bla@some.com]
> [john@home.com]

有一个解决方案涉及将Internal_field_separator(IFS)设置为;。我不确定这个答案发生了什么,如何将IFS重置为默认值?

回复:IFS解决方案,我尝试了这个,它奏效了,我保留了旧的IFS,然后恢复它:

IN="bla@some.com;john@home.com"

OIFS=$IFS
IFS=';'
mails2=$IN
for x in $mails2
do
    echo "> [$x]"
done

IFS=$OIFS

顺便说一下,当我尝试

mails2=($IN)

在循环中打印时,我只得到了第一个字符串,$in周围没有括号,它可以工作。


当前回答

这里有一些很酷的答案(特别是勘误表),但对于类似于其他语言中的分裂的东西——这就是我最初的问题的意思——我决定了这个问题:

IN="bla@some.com;john@home.com"
declare -a a="(${IN/;/ })";

现在,${a[0]}、${a[1]}等都是您所期望的。使用${#a[*]}来表示术语的数量。或者迭代,当然:

for i in ${a[*]}; do echo $i; done

重要说明:

这在没有空间可担心的情况下有效,这解决了我的问题,但可能无法解决你的问题。在这种情况下,使用$IFS解决方案。

其他回答

这是最简单的方法。

spo='one;two;three'
OIFS=$IFS
IFS=';'
spo_array=($spo)
IFS=$OIFS
echo ${spo_array[*]}

这是一个干净的3行:

in="foo@bar;bizz@buzz;fizz@buzz;buzz@woof"
IFS=';' list=($in)
for item in "${list[@]}"; do echo $item; done

其中IFS根据分隔符分隔单词,()用于创建数组。然后使用[@]将每个项目作为单独的单词返回。

如果之后有任何代码,还需要恢复$IFS,例如未设置IFS。

如果您不介意立即处理它们,我喜欢这样做:

for i in $(echo $IN | tr ";" "\n")
do
  # process
done

您可以使用这种循环来初始化数组,但可能有一种更简单的方法。

这也适用于:

IN="bla@some.com;john@home.com"
echo ADD1=`echo $IN | cut -d \; -f 1`
echo ADD2=`echo $IN | cut -d \; -f 2`

小心,这个解决方案并不总是正确的。万一你通过了“bla@some.com“仅,它将分配给ADD1和ADD2。

除了已经提供的精彩答案之外,如果只是打印数据的问题,您可以考虑使用awk:

awk -F";" '{for (i=1;i<=NF;i++) printf("> [%s]\n", $i)}' <<< "$IN"

这将字段分隔符设置为;,以便它可以用for循环遍历字段并相应地打印。

Test

$ IN="bla@some.com;john@home.com"
$ awk -F";" '{for (i=1;i<=NF;i++) printf("> [%s]\n", $i)}' <<< "$IN"
> [bla@some.com]
> [john@home.com]

使用另一个输入:

$ awk -F";" '{for (i=1;i<=NF;i++) printf("> [%s]\n", $i)}' <<< "a;b;c   d;e_;f"
> [a]
> [b]
> [c   d]
> [e_]
> [f]