【问题标题】:Find items common between two Bash arrays查找两个 Bash 数组之间的共同项
【发布时间】:2018-04-24 03:46:56
【问题描述】:

我有下面的 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 结尾。它只是缩写形式。

【问题讨论】:

标签: arrays linux bash shell


【解决方案1】:

您可以将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 pair 提供排序后的输入流供通讯使用
  • comm -12 发出两个流共有的项目

【讨论】:

  • 有趣.. 以前从未使用过 comm。今天学到了新东西。谢谢!
【解决方案2】:

除了 codeforester 的回答,我还能想到另外两种方法:

  1. $range 的值加载为关联数组的键。这 值将是1。循环遍历${number1[@]} 的每个成员和 ${number2[@]},针对关联中的值测试它们 数组。
  2. 使用 codeforester 的 printf ... | sort 技巧,但同时通过管道传输列表 以及通过sort | uniq -c 的范围,然后用grep 查找 重复。

我不确定其中任何一个是否是对您的代码的实际改进。 ...我会创建一个“查找重复项”shell 函数,但否则您的代码看起来很可靠。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-14
    • 2018-05-12
    • 2015-10-27
    • 2017-07-06
    • 1970-01-01
    • 2015-07-20
    • 2011-04-01
    • 1970-01-01
    相关资源
    最近更新 更多