合并文件进阶需求:主机名匹配关联目录的高效方法咨询
高效实现主机名与目录名的匹配关联
需求回顾
- 两个输入文件:
good:每行一个可访问主机名,示例内容:b01-1-ws001 b01-ws001 b07-1-control b07-1-ws001 b07-2-control ...- 目录文件(暂称
dirs):每行一个目录名,示例内容:b01-1 b07 b07-1 b07-2 b16 b18 b21 b22
- 输出要求:每行格式为
主机名,匹配的目录名列表(空格分隔),示例:b07-1-control,b07 b07-1 b07-2 b07-2-control,b07 b07-1 b07-2 ...
优化方案
你的原始算法是逐行读取主机名后遍历所有目录,当文件规模较大时效率会很低。以下是几种更高效的实现思路:
1. 预处理目录,建立前缀映射
先把所有目录按顶级前缀(比如b07-1提取b07,b01-1提取b01)分组,存储为字典结构:
- 键:顶级前缀(如
b07、b01) - 值:该前缀下的所有目录名列表
处理主机名时,只需要提取它的顶级前缀,直接从字典中取出对应的目录列表即可,无需遍历全部目录。
示例Python实现
# 预处理目录文件 dir_groups = {} with open('dirs', 'r') as f: for line in f: dir_name = line.strip() if not dir_name: continue # 提取顶级前缀(按第一个'-'分割,取第一部分) top_prefix = dir_name.split('-')[0] if top_prefix not in dir_groups: dir_groups[top_prefix] = [] dir_groups[top_prefix].append(dir_name) # 处理主机名文件并生成输出 with open('good', 'r') as f_in, open('output.txt', 'w') as f_out: for line in f_in: hostname = line.strip() if not hostname: continue top_prefix = hostname.split('-')[0] # 获取匹配的目录列表,无匹配则为空 matched_dirs = dir_groups.get(top_prefix, []) # 按示例格式写入 f_out.write(f"{hostname},{' '.join(matched_dirs)}\n")
2. 使用Shell工具链(awk/grep)实现
如果习惯用命令行,可以用awk预处理目录,再结合grep快速匹配:
# 第一步:把目录按顶级前缀分组,存为临时文件 awk -F'-' '{print $1 " " $0}' dirs | sort > dir_groups.tmp # 第二步:遍历主机名,提取顶级前缀后匹配对应目录 while read hostname; do prefix=$(echo "$hostname" | cut -d'-' -f1) matched=$(grep "^$prefix " dir_groups.tmp | awk '{print $2}' | tr '\n' ' ') # 去除末尾空格 matched=$(echo "$matched" | sed 's/ $//') echo "$hostname,$matched" done < good > output.txt # 清理临时文件 rm dir_groups.tmp
3. 前缀树(Trie)优化(超大规模场景)
如果主机名和目录数量达到十万级以上,可以用前缀树存储所有目录名,处理每个主机名时遍历前缀树,快速找出所有符合匹配规则的目录,进一步提升查找效率。
说明
以上方案的核心是减少重复遍历,通过预处理把目录按规则分组,让每个主机名的匹配操作从O(n)降到O(1)或O(logn),大幅提升处理效率。
内容的提问来源于stack exchange,提问作者j4nd3r53n
相关产品推荐
相关产品推荐

