Bash实现文件对比:筛选不在手动MAC列表中的扫描MAC
解决方法:筛选扫描MAC中不在手动列表里的项
嘿,我明白你的需求啦!你现在的代码是在找两个数组的交集(同时出现在两个列表里的MAC),但我们要反过来——找出scannedMacs里那些没出现在allMacs里的地址。下面给你两种实用的实现方式:
方法1:修改现有双重循环逻辑
直接调整循环的遍历顺序和判断条件,对每个扫描到的MAC,检查它是否存在于手动列表中:
#!/bin/bash # 假设你已经正确填充了 allMacs 和 scannedMacs 数组 for scannedItem in "${scannedMacs[@]}"; do # 默认标记为“未找到” isPresent=0 # 遍历手动MAC列表,检查当前扫描MAC是否存在 for allItem in "${allMacs[@]}"; do if [[ "$scannedItem" == "$allItem" ]]; then isPresent=1 break # 找到匹配就立刻跳出内层循环,节省时间 fi done # 如果标记还是0,说明这个MAC不在手动列表里,写入文件 if [[ $isPresent -eq 0 ]]; then echo "$scannedItem" >> final.txt fi done
方法2:用关联数组提升效率(推荐)
如果你的MAC列表比较大,双重循环的效率会很低。可以把allMacs转成关联数组(哈希表),这样查找操作的时间复杂度直接降到O(1),速度快很多(需要Bash 4.0及以上版本):
#!/bin/bash # 把手动MAC列表转成关联数组,键就是MAC地址 declare -A allMacsHash for mac in "${allMacs[@]}"; do allMacsHash["$mac"]=1 done # 遍历扫描到的MAC,直接检查是否在哈希表中 for scannedItem in "${scannedMacs[@]}"; do # ! -v 表示“键不存在” if [[ ! -v allMacsHash["$scannedItem"] ]]; then echo "$scannedItem" >> final.txt fi done
小提示
注意MAC地址的格式一致性!比如有些扫描结果可能带冒号、大写字母,而手动列表是小写或不带分隔符,这种情况下可以先统一格式,比如转成小写:
# 处理MAC为小写格式 scannedItem=$(echo "$scannedItem" | tr '[:upper:]' '[:lower:]')
内容的提问来源于stack exchange,提问作者Dark Force
相关产品推荐
相关产品推荐

