배열에서 값을 제거하면 구분 기호가 있는 빈 공간이 있기 때문에 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> 

(연관 배열을 사용할 수도 있지만 키는 정의되지 않은 순서로 나타납니다.)

다른 프로그래밍 언어에서는 이와 같은 작업이 더 잘 수행될 수 있을 것 같습니다.

관련 정보