搜索重复元素数组

时间:2014-02-26 22:50:44

标签: arrays bash duplicates

这一项工作:

arr[0]="XX1 1"
arr[1]="XX2 2" 
arr[2]="XX3 3"
arr[3]="XX4 4"
arr[4]="XX5 5"
arr[5]="XX1 1"
arr[6]="XX7 7"
arr[7]="XX8 8"

duplicate() { printf '%s\n' "${arr[@]}" | sort -cu |& awk -F: '{ print $5 }'; }

duplicate_match=$(duplicate)

echo "array: ${arr[@]}"

# echo "duplicate: $duplicate_match"

[[ ! $duplicate_match ]] || { echo "Found duplicate:$duplicate_match"; exit 0; }

echo "no duplicate"

使用相同的代码,这个不起作用,为什么?

arr[0]="XX"
arr[1]="wXyz" 
arr[2]="ABC"
arr[3]="XX"

2 个答案:

答案 0 :(得分:3)

要检查重复项,此代码更简单,适用于两种情况:

uniqueNum=$(printf '%s\n' "${arr[@]}"|awk '!($0 in seen){seen[$0];c++} END {print c}')

(( uniqueNum != ${#arr[@]} )) && echo "Found duplicates"

编辑:要打印重复项,请使用此awk:

printf '%s\n' "${arr[@]}"|awk '!($0 in seen){seen[$0];next} 1'

如果一行不是seen数组的一部分并且接下来移到下一行,则awk命令存储在数组seen中。最后1仅打印那些重复的行。

答案 1 :(得分:0)

这里有点愚蠢的解决方案。我只是想看看是否可以在没有显式管道的情况下用单个命令执行此操作。 (我认为对于非常大的数组/数组元素,explicit pipes might actually be more efficient。)

请注意,这是对是否存在重复数组元素的测试,尽管awk命令本身可以执行此操作,但不会自行输出重复数组元素。另请注意,如果您不幸的是数组元素包含空格,则下面的内容将不会按照所述进行评估。

[[ $( awk -v RS=" " ' a[$0]++ ' <<< "${arr[@]} " ) ]] && echo "dups found"

说明:

awk -v RS=" "

  • 对每个输入记录执行后续的awk命令,并以空格作为记录分隔符。基本上,这将使awk将每个数组元素视为单独的“行”。

' a[$0]++ '

  • awk命令可完成两件事:

    • 返回数组$0中键a处的值。如果大于0,则打印该行。比较awk ' { $1=$2 } 1 '

    • 向数组$0中的键a的值加1。

<<< "${arr[@]} "

  • 作为awk命令的输入,使用在arr中打印每个元素时创建的字符串作为单独的单词,即用空格分隔加一个额外的空格结束

  • }"之间的空格实际上非常重要,因为没有它,最终的数组元素将空格,因此awk不会将它们 视为不同的“记录”。

[[ $( ... ) ]]

  • 如果包含awk的命令根本没有提供任何输出,则测试结果为0,即TRUE。