如何解决如何在 Bash 的分隔符上拆分字符串?
您可以设置内部字段分隔符(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"
IN="bla@some.com;john@home.com"
arrIN=(${IN//;/ })
echo ${arrIN[1]} # Output: john@home.com
解释:
此构造用(单个空格)替换字符串中所有出现的';'
(初始//
表示全局替换),然后将空格分隔的字符串解释为数组(这就是周围括号的作用)。IN``' '
花括号内用于将每个';'
字符替换为' '
字符的语法称为参数扩展。
有一些常见的陷阱:
-
如果原始字符串有空格,则需要使用IFS:
-
IFS=':'; arrIN=($IN); unset IFS;
-
如果原始字符串有空格并且分隔符是新行,则可以使用以下方式设置IFS:
-
IFS=$'\n'; arrIN=($IN); unset IFS;
解决方法
我将此字符串存储在一个变量中:
IN="bla@some.com;john@home.com"
现在我想用;
分隔符分割字符串,这样我就有:
ADDR1="bla@some.com"
ADDR2="john@home.com"
我不一定需要ADDR1
andADDR2
变量。如果它们是数组的元素那就更好了。
根据以下答案的建议,我最终得到了以下结果:
#!/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
。