繁体   English   中英

查找两个Bash阵列之间常见的项目

[英]Find items common between two Bash arrays

我有下面的shell脚本,其中我有两个数组number1number2 我有一个可变range ,其中包含数字列表。

现在我需要弄清楚number1数组中的所有数字在range变量中也存在。 同样对于number2数组也是如此。 下面是我的shell脚本,它运行正常。

number1=(1220 1374 415 1097 1219 557 401 1230 1363 1116 1109 1244 571 1347 1404)
number2=(411 1101 273 1217 547 1370 286 1224 1362 1091 567 561 1348 1247 1106 304 435 317)
range=90,197,521,540,552,554,562,569:570,573,576,579,583,594,597,601,608:609,611,628,637:638,640:641,644:648
range_f=" "$(eval echo $(echo $range | perl -pe 's/(\d+):(\d+)/{$1..$2}/g;s/,/ /g;'))" "
echo "$range_f"

for item in "${number1[@]}"; do
 if [[ $range_f =~ " $item " ]] ; then
 new_number1+=($item)
 fi
done
echo "new list: ${new_number1[@]}"

for item in "${number2[@]}"; do
 if [[ $range_f =~ " $item " ]] ; then
   new_number2+=($item)
 fi
done
echo "new list: ${new_number2[@]}"

有没有更好的方法来写上面的东西? 截至目前,我有两个for循环迭代,然后计算new_number1new_number2数组。

注意:644:648这样的数字表示,它以644开头,以648结尾。它只是简短形式。

您可以将comm用于进程替换而不是循环:

mapfile -t new_number1 < <(comm -12 <(printf '%s\n' "${number1[@]}" | sort) <(printf '%s\n' $range_f | sort))
mapfile -t new_number2 < <(comm -12 <(printf '%s\n' "${number2[@]}" | sort) <(printf '%s\n' $range_f | sort))
  • mapfile -t name从嵌套进程替换到命名数组
  • printf ... | sort printf ... | sort对为comm提供排序的输入流
  • comm -12发出两个流共有的项

除了codeforester的答案,我还可以想到另外两种方法:

  1. 加载$range的值作为关联数组的键。 值为1 遍历${number1[@]}${number2[@]}每个成员,根据关联数组中的值对它们进行测试。
  2. 使用codeforester的printf ... | sort printf ... | sort技巧,但通过sort | uniq -c管道列表和范围 sort | uniq -c ,然后grep为重复。

我不确定这些中的任何一个是否是对代码的实际改进。 ...我会创建一个'find duplicates'shell函数,但是否则你的代码看起来很稳定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM