一尘不染

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

shell

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

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

现在我想用;分隔符分割字符串,这样我就有:

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

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


根据以下答案的建议,我最终得到了以下结果:

#!/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


阅读 183

收藏
2022-02-07

共2个答案

一尘不染

您可以设置内部字段分隔符(IFS) 变量,然后让它解析成一个数组。当这发生在命令中时,分配 toIFS只发生在该单个命令的环境 (to read) 中。然后它根据IFS变量值将输入解析为一个数组,然后我们可以对其进行迭代。

此示例将解析由 分隔的一行项目;,并将其推入一个数组:

IFS=';' read -ra ADDR <<< "$IN"
for i in "${ADDR[@]}"; do
  # process "$i"
done

另一个示例用于处理 的全部内容$IN,每次输入一行,由 分隔;

while IFS=';' read -ra ADDR; do
  for i in "${ADDR[@]}"; do
    # process "$i"
  done
done <<< "$IN"
2022-02-07
一尘不染

取自Bash shell 脚本拆分数组

IN="bla@some.com;john@home.com"
arrIN=(${IN//;/ })
echo ${arrIN[1]}                  # Output: john@home.com

解释:

此构造用(单个空格)替换字符串中所有出现的';'(初始//表示全局替换),然后将空格分隔的字符串解释为数组(这就是周围括号的作用)。IN``' '

花括号内用于将每个';'字符替换为' '字符的语法称为参数扩展

有一些常见的陷阱:

  1. 如果原始字符串有空格,则需要使用IFS

  2. IFS=':'; arrIN=($IN); unset IFS;

  3. 如果原始字符串有空格并且分隔符是新行,则可以使用以下方式设置IFS

  4. IFS=$'\n'; arrIN=($IN); unset IFS;

2022-02-07