下面的脚本让您将一堆 VLAN 写入一个数组,然后我想用它来删除与“dhcp snooping”行有关的另一段配置
$ cat nm
#!/bin/bash
echo "enter old vlans"
while read line
do
oldvlans=("${oldvlans[@]}" $line)
done
delete=790
for del in ${delete[@]}
do
oldvlans=("${oldvlans[@]/$del}")
done
printf -v joinedoldvlans '%s,' "${oldvlans[@]}"
echo "no ip dhcp snooping vlan ${joinedoldvlans%,}"
$ ./nm
enter old vlans
119
790
999
no ip dhcp snooping vlan 119,,999
我现在遇到的问题是格式。我希望最后一行的输出如下所示:
no ip dhcp snooping vlan 119,999
但我不知道如何解决它。
答案1
嗯,oldvlans=("${oldvlans[@]/$del}")
实际上并没有从数组中删除任何元素,它只是从现有元素中删除给定的字符串。此外,它也会匹配元素中间的给定字符串,例如,具有del=790
, 会1790
变成1
。
我认为除了构建一个新数组之外,没有更好的方法来过滤数组中的值:
a=(111 222 333)
b=()
for x in "${a[@]}"; do
if [[ "$x" != 222 ]]; then
b+=("$x")
fi
done
printf "<%s> " "${b[@]}"; echo
# prints <111> <333>
当然,如果你有一个想要删除的值列表,你至少需要一个测试来看看数组中是否存在某个元素,这在 Bash 中也并不简单。
您也许可以使用稀疏数组,将活动数据放在键/索引:
declare -a vlans=()
# fill the array (from a string here)
while read v; do
vlans+=(["$v"]=1)
done <<< $'111\n790\n1790\n'
# remove these two
for r in 790 999; do
unset "vlans[$r]"
done
printf "<%s> " "${!vlans[@]}"; echo
# prints <1790> <111>
(您也可以使用关联数组,但键将以不确定的顺序出现。)
在我看来,用其他编程语言可能会更好地完成这样的事情。