Сравните элементы массива и определите, какая строка элемента является частью другого в bash - PullRequest
1 голос
/ 23 мая 2019

У меня есть массив:

src_dir=( /etc /var/www /var /var/html /home/user)

Я хочу вывод, как это:

/etc
/var contains /var/www /var/html
/home/user

Я пробовал до сих пор:

src_dir=( /etc /var/www /var /var/html /home/user)
declare exclude
for src in ${src_dir[@]}; do
    if ! [[ " $src " =~ $exclude ]]; then
        exclude+=("$src")
    fi
done

1 Ответ

1 голос
/ 23 мая 2019

Попробуйте это Shellcheck -чистый код:

#! /bin/bash -p

src_dir=( /etc /var/www /var /var/html /home/user)

for src in "${src_dir[@]}"; do
    # Determine if $src contains other elements ($is_container), and which
    # elements contain it ($containers)
    is_container=0
    containers=()   # Elements that this element is part of
    for src2 in "${src_dir[@]}"; do
        if [[ $src2 == "$src" ]] ; then
            # Don't count an element as being part of itself
            continue
        elif [[ $src == *"$src2"* ]]; then
            is_container=1
            break
        elif [[ $src2 == *"$src"* ]] ; then
            containers+=( "$src2" )
        fi
    done

    # Skip elements that contain other elements.
    # Print elements elements that don't contain other elements, and any
    # elements that contain them.
    if (( is_container )) ; then
        continue
    elif (( ${#containers[*]} > 0 )) ; then
        printf '%s is contained in' "$src"
        printf ' %q' "${containers[@]}"
        printf '\n'
    else
        printf '%s\n' "$src"
    fi
done
  • Соответствие регулярному выражению (=~) имеет некоторые странности в Bash, и его лучше избегать.Здесь достаточно простого сопоставления с [[ ... == ... ]].
  • Элементы не указаны как содержащиеся в других элементах, если они содержат какие-либо элементы.Так что если у вас есть (/home /home/user /home/user/dir), то /home/user не будет указан как содержащийся в /home/user/dir.Это может быть не то, что вы хотите.
  • Элементы сравниваются как чистые строки.Не предпринимается попытка проверить наличие пути к файловой системе.Так, например, /home/user считается содержащимся в /home/user2.Это может быть не то, что вам нужно.
  • Если элемент содержит два других элемента, он будет указан как содержащий их оба.Таким образом, /home и /user будут перечислены как содержащиеся в /home/user.Это может быть не то, что вы хотите.
...