39

以下是我创建 bash 数组的方法:

while read line
do
   myarr[$index]=$line
   index=$(($index+1))
done < lines.txt

文件“lines.txt”由以下字符串组成

hello big world!
how are you
where am I

创建后,${myarr[@]}我可以轻松访问此数组中的每个元素(行)

echo ${myarr[2]}

但是如果我只想提取world!呢?是否可以world!从 0 的元素中提取myarr?最重要的是,是否可以从myarr元素中提取任何最后一个单词?

我知道在 python 中你可以做到这一点myarr[0][3],这会成功,那么 bash 呢?

4

4 回答 4

42

这是许多方法之一

set ${myarr[2]}
echo $3
于 2013-03-28T15:33:24.287 回答
19

您可以使用变量扩展中的修饰符从字符串(即数组元素的含义)中提取单词:(#删除前缀)、##(删除前缀,贪婪)、%(删除后缀)和%%(删除后缀,贪婪)。

$ myarr=('hello big world!' 'how are you' 'where am I')
$ echo "${myarr[0]}"      # Entire first element of the array
hello big world!
$ echo "${myarr[0]##* }"  # To get the last word, remove prefix through the last space
world!
$ echo "${myarr[0]%% *}"  # To get the first word, remove suffix starting with the first space
hello
$ tmp="${myarr[0]#* }"    # The second word is harder; first remove through the first space...
$ echo "${tmp%% *}"       # ...then get the first word of what remains
big
$ tmp="${myarr[0]#* * }"  # The third word (which might not be the last)? remove through the second space...
$ echo "${tmp%% *}"       # ...then the first word again
world!

正如您所看到的,您可以在这里变得相当花哨,但在某些时候@chepner 将其转换为数组的建议变得容易得多。此外,我建议用于提取第二个 etc 单词的公式有点脆弱:如果您使用我的公式来提取只有两个单词的字符串的第三个单词,第一次修剪将失败,并且最终会打印第一个(!)单词而不是空格。此外,如果您连续有两个空格,这会将其视为一个长度为零的单词,每边都有一个空格......

顺便说一句,在构建数组时,我认为它使用起来更简洁,+=(newelement)而不是显式地跟踪数组索引:

myarr=()
while read line, do
    myarr+=("$line")
done < lines.txt
于 2013-03-28T20:33:24.227 回答
7

类似于stephen-penny 的答案,但没有覆盖外壳/函数位置参数。

a=(${myarr[2]})
echo ${a[3]}
于 2019-08-18T15:56:27.187 回答
5

使用索引从数组中打印特定元素:

echo ${my_array[2]}

打印数组中的所有元素:

for i in "${my_array[@]}"
do
    echo $i
done
于 2019-08-20T08:41:17.793 回答