配列から値を削除すると、区切り文字を含む空のスペースがあるため、printfが混乱します。

配列から値を削除すると、区切り文字を含む空のスペースがあるため、printfが混乱します。

以下のスクリプトを使用すると、アレイに複数のVLANを書き込むことができます。これを使用して、「dhcpスヌーピング」ラインに関連する他の構成部分を削除しようとします。

$ 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}")実際には、配列から要素を削除せずに、既存の要素から与えられた文字列を削除するだけです。また、要素の中央にある指定された文字列とも一致します。たとえば、withはにdel=790なります。17901

新しい配列を作成するよりも、配列の値をフィルタリングするより良い方法はないと思います。

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> 

(連想配列を使用することもできますが、キーは未定義の順序で表示されます。)

他のプログラミング言語では、このようなことをよりよく行うことができるようです。

関連情報