在bash中将字符串拆分为数组 [英] Split string into array in bash

查看:85
本文介绍了在bash中将字符串拆分为数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种方法,可以将bash中的字符串分割成定界符字符串,并将其放置在数组中.

I am looking for a way to split a string in bash over a delimiter string, and place the parts in an array.

简单情况:

#!/bin/bash
b="aaaaa/bbbbb/ddd/ffffff"
echo "simple string: $b"

IFS='/' b_split=($b)
echo ;
echo "split"
for i in ${b_split[@]}
do
    echo "------ new part ------"
    echo "$i"
done

提供输出

simple string: aaaaa/bbbbb/ddd/ffffff

split
------ new part ------
aaaaa
------ new part ------
bbbbb
------ new part ------
ddd
------ new part ------
ffffff

更复杂的情况:

#!/bin/bash
c=$(echo "AA=A"; echo "B=BB"; echo "======="; echo "C==CC"; echo "DD=D"; echo "======="; echo "EEE"; echo "FF";)
echo "more complex string"
echo "$c";
echo ;
echo "split";

IFS='=======' c_split=($c) ;#    <----    LINE TO BE CHANGED 

for i in ${c_split[@]}
do
    echo "------ new part ------"
    echo "$i"
done

给出输出:

more complex string
AA=A
B=BB
=======
C==CC
DD=D
=======
EEE
FF

split
------ new part ------
AA
------ new part ------
A
B
------ new part ------
BB

------ new part ------

------ new part ------

------ new part ------

------ new part ------

------ new part ------

------ new part ------

------ new part ------

C
------ new part ------

------ new part ------
CC
DD
------ new part ------
D

------ new part ------

------ new part ------

------ new part ------

------ new part ------

------ new part ------

------ new part ------

------ new part ------

EEE
FF

我希望第二个输出像

------ new part ------
AA=A
B=BB
------ new part ------
C==CC
DD=D
------ new part ------
EEE
FF

即将字符串分割成一个字符顺序,而不是一个.我该怎么办?

I.e. to split the string on a sequence of characters, instead of one. How can I do this?

我正在寻找仅会在第二个脚本中修改此行的答案:

I am looking for an answer that would only modify this line in the second script:

IFS='=======' c_split=($c) ;#    <----    LINE TO BE CHANGED 

推荐答案

IFS消除歧义

IFS表示输入字段分隔符,为 list of characters that could be used as separators .

IFS disambiguation

IFS mean Input Field Separators, as list of characters that could be used as separators.

默认情况下,此设置为 \t\n,表示空格制表 和/或任何数量(大于零) 换行符可以是一个 separator .

By default, this is set to \t\n, meaning that any number (greater than zero) of space, tabulation and/or newline could be one separator.

所以字符串:

 "    blah  foo=bar 
 baz  "

前导和尾随分隔符将被忽略,该字符串仅包含3个 部分:blahfoo=barbaz.

Leading and trailing separators would be ignored and this string will contain only 3 parts: blah, foo=bar and baz.

如果您知道在字符串中未使用有效的字段分隔符,则可以使用IFS分隔字符串.

Splitting a string using IFS is possible if you know a valid field separator not used in your string.

OIFS="$IFS"
IFS='§'
c=$'AA=A\nB=BB\n=======\nC==CC\nDD=D\n=======\nEEE\nFF'
c_split=(${c//=======/§})
IFS="$OIFS"
printf -- "------ new part ------\n%s\n" "${c_split[@]}"

------ new part ------
AA=A
B=BB

------ new part ------

C==CC
DD=D

------ new part ------

EEE
FF

但这仅在字符串不包含§时起作用.

But this work only while string do not contain §.

您可以使用其他字符,例如IFS=$'\026';c_split=(${c//=======/$'\026'}),但是无论如何,这可能会涉及到臭虫.

You could use another character, like IFS=$'\026';c_split=(${c//=======/$'\026'}) but anyway this may involve furter bugs.

您可以浏览字符映射表以查找不在您的字符串中的人:

You could browse character maps for finding one who's not in your string:

myIfs=""
for i in {1..255};do
    printf -v char "$(printf "\\\%03o" $i)"
        [ "$c" == "${c#*$char}" ] && myIfs="$char" && break
  done
if ! [ "$myIFS" ] ;then
    echo no split char found, could not do the job, sorry.
    exit 1
  fi

但我发现此解决方案有些过分.

but I find this solution a little overkill.

的问题下,我们可以使用这种bashism :

Under bash, we could use this bashism:

b="aaaaa/bbbbb/ddd/ffffff"
b_split=(${b//// })

实际上,此语法${varname//将启动转换(用/分隔),将所有/出现的位置替换为空格之前,将其分配给数组b_split.

In fact, this syntaxe ${varname// will initiate a translation (delimited by /) replacing all occurences of / by a space , before assigning it to an array b_split.

当然,它仍然使用IFS并在空格上分割数组.

Of course, this still use IFS and split array on spaces.

这不是最好的方法,但是可以处理特定的情况.

This is not the best way, but could work with specific cases.

您甚至可以在拆分之前丢下多余的空格:

You could even drop unwanted spaces before splitting:

b='12 34 / 1 3 5 7 / ab'
b1=${b// }
b_split=(${b1//// })
printf "<%s>, " "${b_split[@]}" ;echo
<12>, <34>, <1>, <3>, <5>, <7>, <ab>, 

或交换他们...

b1=${b// /§}
b_split=(${b1//// })
printf "<%s>, " "${b_split[@]//§/ }" ;echo
<12 34 >, < 1 3 5 7 >, < ab>, 

strings 上的分割线:

因此,您不必不要使用IFS来表示您的意思,但

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆