如何在Bash中的分隔符上拆分字符串?

这篇博客讨论了如何在Bash shell中使用不同方法按分隔符拆分字符串。内容涵盖了IFS(Internal Field Separator)的设置、数组的使用,以及各种解决方案,包括兼容不同Bash版本的技巧。文章提供了多个示例,展示了如何将字符串拆分成数组,特别提到了bash 4.4及以上版本的新特性。
摘要由CSDN通过智能技术生成

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

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

现在我想用拆分字符串; 分隔符,以便我有:

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

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


经过以下答案的建议后,我得出了以下结论:

#!/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重置为默认值?

RE: 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括弧,它可以工作。


#1楼

单线分割用';'分隔的字符串 放入数组是:

IN="bla@some.com;john@home.com"
ADDRS=( $(IFS=";" echo "$IN") )
echo ${ADDRS[0]}
echo ${ADDRS[1]}

这仅将IFS设置在子外壳中,因此您不必担心保存和恢复其值。


#2楼

这也适用:

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。


#3楼

这里有一些很酷的答案(特别是错误),但是对于类似于其他语言的拆分来说,这就是我最初想表达的意思,我就此解决了:

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解决方案。


#4楼

我认为AWK是解决您问题的最佳且有效的命令。 默认情况下,几乎每个Linux发行版都包含AWK。

echo "bla@some.com;john@home.com" | awk -F';' '{print $1,$2}'

会给

bla@some.com john@home.com

当然,您可以通过重新定义awk打印字段来存储每个电子邮件地址。


#5楼

兼容答案

对于这个SO问题,在已经有很多不同的方法可以做到这一点。 但是bash具有许多特殊功能,即所谓的bashism可以很好地工作,但是不能在任何其他

特别是, 数组关联数组模式替换是纯bashism ,在其他shell下可能不起作用。

在我的Debian GNU / Linux上 ,有一个称为标准外壳,但是我知道很多人喜欢使用

最后,在很小的情况下,有一个名为的特殊工具,带有他自己的外壳解释器( )。

要求的字串

SO问题中的字符串示例是:

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

由于这可能对空格有用,并且因为空格可以修改例程的结果,所以我更喜欢使用以下示例字符串:

 IN="bla@some.com;john@home.com;Full Name <fulnam@other.org>"

根据定界符分割字符串(版本> = 4.2)

bash下,我们可以使用数组IFS

var="bla@some.com;john@home.com;Full Name <fulnam@other.org>"

 oIFS="$IFS" IFS=";" declare -a fields=($var) IFS="$oIFS" unset oIFS 

IFS=\; read -a fields <<<"$IN"

在最近的bash下使用此语法不会为当前会话更改$IFS ,而仅会为当前命令更改:

set | grep ^IFS=
IFS=$' \t\n'

现在&

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值