如何删除bash中现有数组中的重复元素?

时间:2019-02-21 00:41:51

标签: bash unix

如何创建仅包含Array中存在的唯一元素的newArray?

例如:ARRAY分别在ARRAY [0-5]处包含元素aa ab bb aa ab cc

当我打印newARRAY时,我只希望aa ab bb cc分别位于newARRAY [0-3]。

我已经搜索了一段时间的堆栈溢出,但是没有任何东西可以解决我的问题。我尝试做newARRAY=$(ARRAY[@] | sort -u | uniq,但是重复的元素仍然存在。

2 个答案:

答案 0 :(得分:2)

天真的方法

要获取arr的唯一元素并假定没有元素包含换行符,则:

$ printf "%s\n" "${arr[@]}" | sort -u
aa
ab
bb
cc

更好的方法

要获得一个以NUL分隔的列表,即使有换行符也可以使用:

$ printf "%s\0" "${arr[@]}" | sort -uz
aaabbbcc

(这当然在终端上看起来很丑,因为它不显示NUL。)

将它们放在一起

要在newArr中捕获结果:

$ newArr=(); while IFS= read -r -d '' x; do newArr+=("$x"); done < <(printf "%s\0" "${arr[@]}" | sort -uz)

运行上述命令后,我们可以使用declare来验证newArr是我们想要的数组:

$ declare -p newArr
declare -a newArr=([0]="aa" [1]="ab" [2]="bb" [3]="cc")

对于那些喜欢将代码分散在多行上的人,以上内容可以重写为:

newArr=()
while IFS= read -r -d '' x
do
    newArr+=("$x")
done < <(printf "%s\0" "${arr[@]}" | sort -uz)

其他评论

不要将所有大写形式用作变量名。系统和外壳程序使用所有大写字母作为名称,并且您不想意外覆盖其中之一。

答案 1 :(得分:0)

您可以使用一个关联数组来跟踪所见元素:

#!/bin/bash

ARRAY=(aa ab bb aa ab cc)

unset dupes # ensure it's empty
declare -A dupes

for i in "${ARRAY[@]}"; do
    if [[ -z ${dupes[$i]} ]]; then
        NEWARRAY+=("$i")
    fi
    dupes["$i"]=1
done
unset dupes # optional

printf "[%s]" "${ARRAY[@]}"
echo
printf "[%s]" "${NEWARRAY[@]}"
echo