在bash中查找两个数组之间的对的最有效方法

在bash中查找两个数组之间的对的最有效方法,bash,shell,sh,Bash,Shell,Sh,我有两个大数组,其中存储了散列值。我试图找到最好的方法来验证数组_a中的所有哈希值是否也在数组_b中找到。到目前为止,我得到的最好的结果是 将哈希文件导入数组 对每个数组进行排序 For循环通过数组_a 在数组_a的for循环内部,对数组_b进行另一次for查找似乎效率低下。 如果在数组_b中找到未设置的值 将“查找”值设置为1并断开循环 如果数组_a没有与文件匹配的输出。 我有大的图像,我需要验证是否已上传到网站和哈希值匹配。我已经从原始文件创建了一个文件,并将网站上的文件刮去,以创建第二个哈

我有两个大数组,其中存储了散列值。我试图找到最好的方法来验证数组_a中的所有哈希值是否也在数组_b中找到。到目前为止,我得到的最好的结果是

将哈希文件导入数组 对每个数组进行排序 For循环通过数组_a 在数组_a的for循环内部,对数组_b进行另一次for查找似乎效率低下。 如果在数组_b中找到未设置的值 将“查找”值设置为1并断开循环 如果数组_a没有与文件匹配的输出。 我有大的图像,我需要验证是否已上传到网站和哈希值匹配。我已经从原始文件创建了一个文件,并将网站上的文件刮去,以创建第二个哈希值列表。尽量保持这一点,所以只使用典型的bash功能

#!/bin/bash

array_a=($(< original_sha_values.txt))
array_b=($(< sha_values_after_downloaded.txt))

# Sort to speed up.
IFS=$'\n' array_a_sorted=($(sort <<<"${array_a[*]}"))
unset IFS
IFS=$'\n' array_b_sorted=($(sort <<<"${array_b[*]}"))
unset IFS

for item1 in "${array_a_sorted[@]}" ; do
  found=0

  for item2 in "${!array_b_sorted[@]}" ; do
    if [[ $item1 == ${array_b_sorted[$item2]} ]]; then
      unset 'array_b_sorted[item2]'
      found=1
      break
    fi
  done

  if [[ $found == 0 ]]; then
    echo "$item1" >> hash_is_missing_a_match.log
  fi
done

两个阵列都有12000行64位哈希,比较起来需要20多分钟。有没有办法提高速度?

你做得很辛苦

如果任务是:查找文件1中的条目,而不是文件2中的条目。这里有一个较短的方法

$ comm -23 <(sort f1) <(sort f2)

你做得很辛苦

如果任务是:查找文件1中的条目,而不是文件2中的条目。这里有一个较短的方法

$ comm -23 <(sort f1) <(sort f2)

我认为karakfa的答案可能是最好的方法,如果您只想完成它,而不担心优化bash代码的话

但是,如果您仍然希望在bash中执行此操作,并且愿意使用某些特定于bash的功能,则可以使用关联数组而不是两个常规数组来节省大量时间:

# Read the original hash values into a bash associative array

declare -A original_hashes=()
while read hash; do
  original_hashes["$hash"]=1
done < original_sha_values.txt

# Then read the downloaded values and check each one to see if it exists
# in the associative array. Lookup time *should* be O(1)

while read hash; do
  if [[ -z "${original_hashes["$hash"]+x}" ]]; then
    echo "$hash" >> hash_is_missing_a_match.log
  fi
done < sha_values_after_downloaded.txt

在这种情况下,您仍然只需要对一个文件进行排序,而不是对两个文件进行排序。

我认为karakfa的答案可能是最好的方法,如果您只想完成它,而不必担心优化bash代码的话

但是,如果您仍然希望在bash中执行此操作,并且愿意使用某些特定于bash的功能,则可以使用关联数组而不是两个常规数组来节省大量时间:

# Read the original hash values into a bash associative array

declare -A original_hashes=()
while read hash; do
  original_hashes["$hash"]=1
done < original_sha_values.txt

# Then read the downloaded values and check each one to see if it exists
# in the associative array. Lookup time *should* be O(1)

while read hash; do
  if [[ -z "${original_hashes["$hash"]+x}" ]]; then
    echo "$hash" >> hash_is_missing_a_match.log
  fi
done < sha_values_after_downloaded.txt

在这种情况下,您仍然只需要对一个文件进行排序,而不是对两个文件进行排序。

您应该能够按顺序逐步执行迭代,而不是嵌套循环。这将导致时间复杂度为On[排序后,其本身在lg n上]。请参阅的“合并”部分。请使用其他语言。bash不是一种数据处理语言,它是一种用于运行执行数据处理的各种程序的粘合语言。您应该能够按顺序逐步执行迭代,而不是嵌套循环。这将导致时间复杂度为On[排序后,其本身在lg n上]。请参阅的“合并”部分。请使用其他语言。bash不是一种数据处理语言,它是一种用于运行各种数据处理程序的粘合语言。我不知道为什么,但如果f1有一个副本,它会错误地将其报告为不匹配。如果只有一个文件有一个副本,则为不匹配。如果要忽略重复记录,请添加-u选项进行排序。我不确定为什么,但如果f1有重复记录,它将错误地将其报告为不匹配。如果只有一个文件有重复记录,则为不匹配。如果要忽略重复记录,请添加-u选项进行排序。
done < <(sort sha_values_after_downloaded.txt)