如何匹配不同文件中带不同扩展名的相似文件名并合并对应字段?
解决CSV文件按无扩展名文件名匹配并合并复杂度字段的问题
需求说明
需要将两个CSV文件(file1.csv对应Java文件数据,file2.csv对应Python文件数据)中去除扩展名后文件名相同的条目,提取各自的cognitive_complexity字段,合并成新的CSV文件,最终保留匹配的无扩展名文件名、Java侧复杂度、Python侧复杂度。
源文件内容
file1.csv(Java文件复杂度数据)
file_name,cognitive_complexity,working_memory 001_Two_Sum.java,3,0 002_Add_Two_Numbers.java,11,0 012_Integer_to_Roman.java,3,0
file2.csv(Python文件复杂度数据)
file_name,method_name,cognitive_complexity,size,working_memory 001_Two_Sum,twoSum,5,82,7 002_Add_Two_Numbers,addTwoNumbers,7,86,8 003_Longest_Substring_Without_Repeating_Characters,lengthOfLongestSubstring,4,77,7
期望输出结果
file_name,java_cognitive_complexity,python_cognitive_complexity 001_Two_Sum,3,5 002_Add_Two_Numbers,11,7
解决方案
推荐用awk工具实现,比单纯结合grep和循环更高效,以下是两种可行方案:
方案1:单命令直接合并(无临时文件)
awk -F',' ' # 处理第一个输入文件file1.csv,构建文件名到Java复杂度的映射 NR==FNR { if (NR>1) { gsub(/\.java$/, "", $1) # 去掉文件名的.java扩展名 java_map[$1] = $2 } next } # 处理第二个输入文件file2.csv,先输出新表头 FNR==1 { print "file_name,java_cognitive_complexity,python_cognitive_complexity" next } # 只输出能匹配到Java数据的条目,合并字段 java_map[$1] != "" { print $1 "," java_map[$1] "," $3 } ' file1.csv file2.csv > result.csv
方案2:分步处理(适合理解过程)
- 提取file1中无扩展名的文件名和对应Java复杂度,生成临时映射文件:
awk -F',' 'NR>1 { gsub(/\.java$/, "", $1); print $1 "," $2 }' file1.csv > java_data.txt
- 读取映射文件,匹配file2中的条目并生成结果:
awk -F',' ' BEGIN { print "file_name,java_cognitive_complexity,python_cognitive_complexity" # 加载Java复杂度映射表 while ((getline line < "java_data.txt") > 0) { split(line, arr, ",") java_map[arr[1]] = arr[2] } } NR>1 && java_map[$1] != "" { print $1 "," java_map[$1] "," $3 } ' file2.csv > result.csv
- 清理临时文件(可选):
rm java_data.txt
补充:结合grep+循环的实现方式
如果一定要用你提到的grep和循环逻辑,可按以下步骤操作:
- 提取file1中无扩展名的文件名:
awk 'NR>1 { gsub(/\.java$/, "", $1); print $1 }' file1.csv > file1_names.txt
- 匹配file2中对应的条目:
grep -F -f file1_names.txt file2.csv > matched_python.txt
- 用循环构建映射并输出结果(效率较低,适合小文件):
# 构建Java复杂度映射 declare -A java_map while IFS=, read -r name val; do java_map["$name"]=$val done < <(awk -F',' 'NR>1 { gsub(/\.java$/, "", $1); print $1 "," $2 }' file1.csv) # 输出表头并合并数据 echo "file_name,java_cognitive_complexity,python_cognitive_complexity" while IFS=, read -r name _ py_val _ _; do if [[ -n "${java_map[$name]}" ]]; then echo "$name,${java_map[$name]},$py_val" fi done < matched_python.txt > result.csv # 清理临时文件 rm file1_names.txt matched_python.txt
内容的提问来源于stack exchange,提问作者funnybunny
相关产品推荐
相关产品推荐

