【问题标题】:How to remove duplicate elements in an existing array in bash? [duplicate]如何在bash中删除现有数组中的重复元素? [复制]
【发布时间】:2019-07-14 19:12:10
【问题描述】:

如何创建一个只包含 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,但重复的元素仍然存在。

【问题讨论】:

    标签: bash unix


    【解决方案1】:

    天真的方法

    要获取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)
    

    补充说明

    变量名不要全部大写。系统和 shell 的名称全部大写,您不想意外覆盖其中一个。

    【讨论】:

    • 我得到:意外标记附近的语法错误
    • 现在可以工作了 - 我使用 sh 来触发脚本,而不是 bash - thx
    【解决方案2】:

    您可以使用关联数组来跟踪您看到的元素:

    #!/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
    

    【讨论】:

      猜你喜欢
      • 2019-03-23
      • 2017-11-17
      • 2018-02-14
      • 2020-05-08
      • 2019-05-01
      • 2017-08-12
      • 2016-12-08
      • 2013-05-20
      相关资源
      最近更新 更多