比较数组元素并确定bash中哪个元素的字符串是另一个字符串的一部分

时间:2019-05-23 02:35:19

标签: string bash compare contains

我有一个数组:

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 个答案:

答案 0 :(得分:1)

尝试使用此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中。那可能不是您想要的。