使用shell脚本比较两个不同的数组

7ajki6be  于 2023-08-07  发布在  Shell
关注(0)|答案(3)|浏览(151)

如何比较两个数组并在shell脚本中显示结果?
假设我们有两个数组如下:

list1=( 10 20 30 40 50 60 90 100 101 102 103 104)
list2=( 10 20 30 40 50 60 70 80 90 100 )

字符串
我的要求是按顺序比较这两个数组,结果只显示为从list1(101 102 103 104)。它不应该包括值7080,这些值存在于list2中,但不存在于list1中。
这并没有帮助,因为它包含了所有内容:

echo "${list1[@]}" "${list2[@]}" | tr ' ' '\n' | sort | uniq -u


我在下面做了这样的尝试,但为什么不起作用?

list1=( 10 20 30 40 50 60 70 90 100 101 102 103 104)
list2=( 10 20 30 40 50 60 70 80 90 100 )

for (( i=0; i<${#list1[@]}; i++ )); do
for (( j=0; j<${#list2[@]}; j++ )); do
     if [[ ${list1[@]} == ${list2[@] ]]; then
         echo 0
         break
             if [[  ${#list2[@]} == ${#list1[@]-1} && ${list1[@]} != ${list2[@]} ]];then
             echo ${list3[$i]}
         fi
     fi
done
done

ifsvaxew

ifsvaxew1#

你可以使用comm来实现:

readarray -t unique < <(
    comm -23 \
        <(printf '%s\n' "${list1[@]}" | sort) \
        <(printf '%s\n' "${list2[@]}" | sort)
)

字符串
导致

$ declare -p unique
declare -a unique=([0]="101" [1]="102" [2]="103" [3]="104")


或者,要获得所需的格式,

$ printf '(%s)\n' "${unique[*]}"
(101 102 103 104)


comm -23接受两个排序后的文件(这里使用sort),并打印第一个文件所特有的每一行;进程替换用于将列表馈送到comm中。
然后,readarray读取输出,并将每行放入unique数组的一个元素中。(请注意,这需要Bash。)
您的尝试失败了,原因之一是您试图在一次比较中比较多个元素:

[[ ${list1[@]} != ${list2[@]} ]]


扩展到

[[ 10 20 30 40 50 60 90 100 101 102 103 104 != 10 20 30 40 50 60 70 80 90 100 ]]


而Bash则抱怨应该使用二元运算符,而不是第二个元素20

yqkkidmi

yqkkidmi2#

也可以用这种方法

#!/bin/ksh

list1=( 10 20 30 40 50 60 90 100 101 102 103 104 )
list2=( 10 20 30 40 50 60 70 80 90 100 )

# Creating a temp array with index being the same as the values in list1

for i in ${list1[*]}; do
        list3[$i]=$i
done

# If value of list2 can be found in list3 forget this value

for j in ${list2[*]}; do
        if [[ $j -eq ${list3[$j]} ]]; then
                unset list3[$j]
        fi
done

# Print the remaining values

print ${list3[*]}

字符串
输出为

101 102 103 104


希望能帮上忙

编辑

如果2个列表相同:

# Print the remaining values

if [[ ${#list3[*]} -eq 0 ]]; then
        print "No differences between the list"
else
        print ${list3[*]}
fi

drnojrws

drnojrws3#

ksh关联数组很方便:

list1=( 10 20 30 40 50 60 90 100 101 102 103 104)
list2=( 10 20 30 40 50 60 70 80 90 100 )
typeset -a onlyList1
typeset -A inList2
for elem in "${list2[@]}"; do inList2["$elem"]=1; done
for elem in "${list1[@]}"; do [[ -v inList2["$elem"] ]] || onlyList1+=("$elem"); done
typeset -p onlyList1

个字符
或者类似地,从list1的所有内容开始,删除list2中的内容:

typeset -A inList1
for elem in "${list1[@]}"; do inList1["$elem"]=1; done
for elem in "${list2[@]}"; do unset inList1["$elem"]; done
onlyList1=( "${!inList1[@]}" )

相关问题