如何匹配同名文件并校验指定列内容,输出不匹配项
目录文件内容匹配校验方案
需求说明
- 匹配
first和second目录下的同名txt文件 - 对每对同名文件,从
first目录的文件中提取第二列(forename),在second目录对应文件中找到相同的forename - 校验
first文件中第4列到最后一列的姓氏内容,与second文件中第6列到最后一列的姓氏内容是否一致 - 不匹配时,按指定格式输出错误信息:
file $first_file_name, no match forename $forename --> first surname: $first_surname || second surname: $second_surname
问题现状
尝试过两段awk代码,但仅输出文件名,无法得到预期的匹配结果。预期输出示例:
file file1.some.thing, no match forename Saeed --> first surname: Fazlollahzadeh || second surname: Fazlollahzade file file2.some.thing, no match forename Foo --> first surname: Bar Ter || second surname: Bar
解决方案
可以用单段awk脚本完成所有逻辑,核心思路是先读取second目录下的文件,把forename和对应的姓氏存储到数组中,再读取first目录的文件进行匹配校验:
awk ' BEGIN { # 遍历second目录下的所有txt文件 for (file in ARGV) { if (ARGV[file] ~ /second\/.*\.txt$/) { fname = ARGV[file] sub(/second\//, "", fname) # 提取文件名(去掉目录前缀) while ((getline line < fname) > 0) { split(line, parts) forename = parts[2] # 拼接第6列到最后一列作为姓氏 surname = "" for (i=6; i<=length(parts); i++) { surname = surname (surname ? " " : "") parts[i] } second_data[fname, forename] = surname } close(fname) delete ARGV[file] # 移除已处理的second文件,避免重复处理 } } } # 处理first目录下的文件 FNR == 1 { fname = FILENAME sub(/first\//, "", fname) # 提取文件名 } { forename = $2 # 拼接第4列到最后一列作为first的姓氏 first_surname = "" for (i=4; i<=NF; i++) { first_surname = first_surname (first_surname ? " " : "") $i } # 检查second中是否存在该forename,且姓氏不匹配 if ((fname, forename) in second_data && first_surname != second_data[fname, forename]) { printf "file %s, no match forename %s --> first surname: %s || second surname: %s\n", fname, forename, first_surname, second_data[fname, forename] } } ' first/*.txt second/*.txt
脚本说明
- BEGIN块:先处理
second目录下的所有文件,将每个文件的(文件名, forename)作为键,对应的姓氏(第6到NF列)作为值存入数组second_data,处理完后从ARGV中移除这些文件,避免后续重复处理。 - 处理first文件:每读取一个
first目录的文件,先提取文件名;对每一行提取forename和第4到NF列的姓氏,然后和second_data中对应的值对比,不匹配则按要求格式输出。
使用方式
直接在终端运行上述脚本即可,确保当前目录下存在first和second两个子目录。
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

