在Bash脚本中,我希望将一行分割成多个片段,并将它们存储在一个数组中。
例如,给定一行:
Paris, France, Europe
我想让结果数组看起来像这样:
array[0] = Paris
array[1] = France
array[2] = Europe
最好是一个简单的实现;速度并不重要。我该怎么做呢?
在Bash脚本中,我希望将一行分割成多个片段,并将它们存储在一个数组中。
例如,给定一行:
Paris, France, Europe
我想让结果数组看起来像这样:
array[0] = Paris
array[1] = France
array[2] = Europe
最好是一个简单的实现;速度并不重要。我该怎么做呢?
当前回答
更新:不要这样做,由于eval的问题。
不那么讲究礼节的:
IFS=', ' eval 'array=($string)'
e.g.
string="foo, bar,baz"
IFS=', ' eval 'array=($string)'
echo ${array[1]} # -> bar
其他回答
下面是一种不设置IFS的方法:
string="1:2:3:4:5"
set -f # avoid globbing (expansion of *).
array=(${string//:/ })
for i in "${!array[@]}"
do
echo "$i=>${array[i]}"
done
这个想法是使用字符串替换:
${string//substring/replacement}
将所有匹配的$substring替换为空白,然后使用替换后的字符串初始化数组:
(element1 element2 ... elementN)
注意:这个答案使用了split+glob操作符。因此,为了防止某些字符(如*)的扩展,暂停该脚本的通配符是个好主意。
当我想解析一个输入时,我看到了这篇文章: word1 word2,…
以上这些对我都没有帮助。使用awk解决了这个问题。如果它能帮助某人:
STRING="value1,value2,value3"
array=`echo $STRING | awk -F ',' '{ s = $1; for (i = 2; i <= NF; i++) s = s "\n"$i; print s; }'`
for word in ${array}
do
echo "This is the word $word"
done
接受的答案适用于一行中的值。如果变量有几行:
string='first line
second line
third line'
我们需要一个非常不同的命令来获取所有的行:
While read -r line;做线+ =(“美元线”);完成了< < <字符串" $ "
或者更简单的bash readarray:
readarray -t lines <<<"$string"
利用printf特性很容易打印所有行:
printf ">[%s]\n" "${lines[@]}"
>[first line]
>[ second line]
>[ third line]
这适用于给定的数据:
$ aaa='Paris, France, Europe'
$ mapfile -td ',' aaaa < <(echo -n "${aaa//, /,}")
$ declare -p aaaa
结果:
declare -a aaaa=([0]="Paris" [1]="France" [2]="Europe")
它也适用于带空格的扩展数据,例如“New York”:
$ aaa="New York, Paris, New Jersey, Hampshire"
$ mapfile -td ',' aaaa < <(echo -n "${aaa//, /,}")
$ declare -p aaaa
结果:
declare -a aaaa=([0]="New York" [1]="Paris" [2]="New Jersey" [3]="Hampshire")
另一种不修改IFS的方法是:
read -r -a myarray <<< "${string//, /$IFS}"
我们不需要更改IFS以匹配所需的分隔符,而是可以通过"${string//, /$IFS}"将所有出现的所需分隔符","替换为$IFS的内容。
也许这对于非常大的字符串来说会很慢?
这是基于Dennis Williamson的回答。