如何在zsh / Unix shell中测试两个数组是否包含相同的元素?

rfbsl7qr  于 2023-06-24  发布在  Shell
关注(0)|答案(2)|浏览(160)

测试2个zsh数组在结构上是否相等(即包含相同的元素)的正确方法是什么?
[[ $array1 == $array2 ]]通过了一些测试,但我不知道它是否是正确的形式,我似乎找不到任何地方讨论的主题。
我目前正在编写zsh代码,但如果不同的话,我也对可移植的答案(bash/POSIX)感兴趣。

hof1towb

hof1towb1#

下面是一个基本函数,它逐个元素地比较两个数组变量:

#!/usr/bin/env zsh

# Takes the names of two array variables
arrayeq() {
    typeset -i i len

    # The P parameter expansion flag treats the parameter as a name of a
    # variable to use
    len=${#${(P)1}} 

    if [[ $len -ne ${#${(P)2}} ]]; then
       return 1
    fi

    # Remember zsh arrays are 1-indexed
    for (( i = 1; i <= $len; i++)); do
        if [[ ${(P)1[i]} != ${(P)2[i]} ]]; then
            return 1
        fi
    done
}

arr1=(1 apple 3 4)
arr2=(1 apple 4 5)

if arrayeq arr1 arr2; then
    print They match
else
    print They are different
fi
c8ib6hqw

c8ib6hqw2#

如果你知道数组不会包含null(并且非常非常少的shell值有null),你可以使用它作为分隔符来比较数组的连接版本:

if [[ ${(j:\0:)ary1} == ${(j:\0:)ary2} ]]; then ...

作为函数:

cmpArrays() {
  [[ ${(Pj:\0:)1:?} == ${(Pj:\0:)2:?} ]]
}

测试:

#!/usr/bin/env zsh

tst() {
  if cmpArrays $1 $2; then
    result=match
  else
    result=nomatch
  fi
  if [[ $result == $3 ]]; then
    print $1 $2 $3 pass
  else
    print $1 $2 $3 FAIL
  fi
}

a1=(a b c)
a2=(a b c)
a3=(a b c d)
a4=('a b' c)
a5=(a c b)
a6=(a b '' c)

tst a1 a2 match
tst a1 a3 nomatch
tst a1 a4 nomatch
tst a1 a5 nomatch
tst a1 a6 nomatch

测试输出:

a1 a2 match pass
a1 a3 nomatch pass
a1 a4 nomatch pass
a1 a5 nomatch pass
a1 a6 nomatch pass

jP标志在zsh文档的参数扩展部分进行了说明。

相关问题