0%

如何从shell数组中删除一个元素

这一篇博客,最开始是想写在shell数组中*和@的区别。但是写着写着,发现之前出问题不是因为 * 和 @,而是因为从数组中删除元素的方式有点小问题。接下来,我将介绍如何从shell数组上删除一个元素。

根据下标删除

先上一个数组

1
2
3
#!/bin/bash

array1=(a b c d a b c d)

我希望从上面的数组中删除第二个元素,如何删除呢?

1
2
3
4
5
6
#!/bin/bash

array1=(a b c d a b c d)
unset array1[1]

echo ${array1[*]}

输出结果:

1
a c d a b c d

根据元素值删除

在有些情况下,我们想删除数组中指定元素,比如删除上述数组中的b。代码如下:

1
2
3
4
5
6
#!/bin/bash

array1=(a b c d a b c d)
array1=( ${array1[*]/b} )

echo ${array1[*]}

结果如下:

1
a c d a c d

如果将array1=( ${array1[*]/b} )中的*换成@,结果输出一样。

${array1[*]/b} 换成 "${array1[*]/b}"

为了更好的测试,加入一个循环,对移除b之后的数组进行循环输出。
代码如下:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

array1=(a b c d a b c d)
array1=( "${array1[*]/b}" )

echo ${array1[*]}

for value in ${array1[@]}
do
echo $value
done

结果如下:

1
2
3
4
5
6
7
a c d a c d
a
c
d
a
c
d

将for循环中的 @ 换成 *

结果和上面一致

将for循环换成for value in "${array1[@]}" 或者 for value in "${array1[*]}"

代码如下:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

array1=(a b c d a b c d)
array1=( "${array1[*]/b}" )

echo ${array1[*]}

for value in "${array1[@]}"
do
echo $value
done

结果如下:

1
2
a c d a c d
a c d a c d

${array1[*]/b} 换成 "${array1[@]/b}"

代码如下:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

array1=(a b c d a b c d)
array1=( "${array1[@]/b}" )

echo ${array1[*]}

for value in ${array1[@]}
do
echo $value
done

结果如下:

1
2
3
4
5
6
7
a c d a c d
a
c
d
a
c
d

将for循环中的 @ 换成 *

结果和上面一致

将for循环换成for value in "${array1[@]}"

代码如下:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

array1=(a b c d a b c d)
array1=( "${array1[@]/b}" )

echo ${array1[*]}

for value in "${array1[@]}"
do
echo $value
done

结果如下:

1
2
3
4
5
6
7
8
9
a c d a c d
a

c
d
a

c
d

将for循环换成for value in "${array1[*]}"

代码如下:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

array1=(a b c d a b c d)
array1=( "${array1[@]/b}" )

echo ${array1[*]}

for value in "${array1[*]}"
do
echo $value
done

结果如下:

1
2
a c d a c d
a c d a c d

删除包含某个字符的元素

为了更好的测试, 换了一个新的数组。代码如下:

1
2
3
4
5
6
#!/bin/bash

array1=(abc bcd cdf dfg)
array1=( "${array1[@]/*b*}" )

echo ${array1[*]}

结果如下:

1
cdf dfg

这个方案和上面的方案,本质上就是截取字符串。

* 和 @ 的区别

These subscripts differ only when the word appears within double quotes. If the word is double-quoted, ${name[*]} expands to a single word with the value of each array member separated by the first character of the IFS variable, and ${name[@]} expands each element of name to a separate word.