如何匹配文件关键词并输出对应URL?已试Awk/grep未获预期结果
解决关键词与URL精确匹配的问题
需求回顾
现有两个文件:
- File1:存储若干关键词,可能包含大小写差异
- File2:存储多个URL,部分URL包含File1中的关键词
需要实现:
- 针对File1中的每个关键词,在File2中查找精确匹配的URL(仅匹配完整关键词,如"abc"不匹配"abcd")
- 未找到匹配项时输出
no matching - 支持大小写不敏感匹配(如"Def"匹配包含"def"的URL)
你的脚本问题分析
你之前的脚本存在几个关键错误:
- 变量名不一致:定义了
file=/bin/file1.txt但使用的是$file1,导致无法正确读取关键词文件 - Awk语法错误:
echo "$a:" | awk '$repos.txt ~ $a {printf $?}'完全不符合Awk的使用逻辑,Awk无法通过这种方式引用外部文件和变量,也没有实现精确匹配的逻辑 - 未处理空白与大小写:没有处理关键词前后的空白字符,也没有考虑大小写匹配的问题
解决方案
方案一:Awk实现(高效适合大文件)
Awk可以一次扫描两个文件,效率更高,适合处理大体积的File1和File2。
创建脚本文件match_keywords.awk:
BEGIN { IGNORECASE = 1 # 开启大小写不敏感匹配 } # 处理第一个文件(File1),存储关键词并记录输入顺序 NR == FNR { kw = $0 gsub(/^[[:space:]]+|[[:space:]]+$/, "", kw) # 去除关键词前后空白 if (kw != "") { keywords[tolower(kw)] = 1 keywords_order[++order_cnt] = kw } next } # 处理第二个文件(File2),收集匹配的URL { url = $0 for (kw in keywords) { # 正则确保关键词前后是非字母数字,实现精确匹配 if (match(url, "(^|[^a-zA-Z0-9])" kw "([^a-zA-Z0-9]|$)")) { matches[kw] = matches[kw] "\n" url } } } # 输出最终结果 END { for (i = 1; i <= order_cnt; i++) { orig_kw = keywords_order[i] lower_kw = tolower(orig_kw) printf "%s:\n", orig_kw if (matches[lower_kw] != "") { print substr(matches[lower_kw], 2) # 移除开头的换行符 } else { print "no matching" } print "" # 空行分隔不同关键词的结果 } }
运行命令:
awk -f match_keywords.awk File1 File2
方案二:Bash+Grep实现(逻辑直观适合小文件)
如果文件体积较小,用Bash结合Grep的方式逻辑更直观,容易理解和修改。
创建脚本文件match_keywords.sh:
#!/bin/bash # 遍历File1的每一行关键词 while IFS= read -r keyword; do # 去除关键词前后的空白字符 trimmed_kw=$(echo "$keyword" | xargs) # 跳过空行 [ -z "$trimmed_kw" ] && continue echo "$trimmed_kw:" # 用Grep做大小写不敏感的精确匹配 # 正则规则:关键词前后是非字母数字,避免匹配包含关键词的更长字符串 grep -i -E "(^|[^a-zA-Z0-9])${trimmed_kw}([^a-zA-Z0-9]|$)" File2 # 检查Grep的退出码:1表示未找到匹配项 if [ $? -eq 1 ]; then echo "no matching" fi # 空行分隔结果 echo done < File1
运行命令:
chmod +x match_keywords.sh ./match_keywords.sh
输出示例
针对你提供的示例文件,运行后会输出:
abc: Https://gitlab.private.com/apm-team/mi_abc_linux1.git Https://gitlab.private.com/apm-team/mi_abc_linux2.git Https://gitlab.private.com/apm-team/mi_abc_linux3.git Def: Https://gitlab.private.com/apm-team/mi_def_linux1.git Https://gitlab.private.com/apm-team/mi_def_linux2.git XYZ: Https://gitlab.private.com/apm-team/mi_xyz_linux1.git Https://gitlab.private.com/apm-team/mi_xyz_linux2.git
内容的提问来源于stack exchange,提问作者Nandunandu
相关产品推荐
相关产品推荐

