Linux服务器下跨文件检测指定位置重复发票号的方法
跨文件检测重复发票号的最优解决方法
针对目录下2000个文件,需提取指定位置的发票号、忽略同一文件内重复、仅找出跨文件重复的发票号及对应文件名的需求,以下是高效的解决方法:
分步处理(清晰易理解)
1. 提取每个文件内唯一的发票号与文件名
用awk遍历所有目标文件,提取指定位置的发票号,同时过滤掉同一文件内的重复条目:
awk '{ # 提取第4位开始的4个字符作为发票号,根据实际位置调整substr参数(格式:substr(字符串, 起始位置, 长度)) inv_no = substr($0, 4, 4) # 用数组记录当前文件已出现的发票号,避免同一文件内重复输出 if (!seen[FILENAME, inv_no]++) { print inv_no, FILENAME } }' *.txt
2. 筛选跨文件重复的条目
将上述结果按发票号排序,再用uniq筛选出重复出现的行:
awk '{ inv_no = substr($0, 4, 4) if (!seen[FILENAME, inv_no]++) { print inv_no, FILENAME } }' *.txt | sort | uniq -D -s 5
注:
-s 5表示跳过前5个字符(4位发票号+1个空格),确保uniq按发票号判断重复。
如果需要更严谨的统计,可通过临时文件分步处理:
# 生成每个文件唯一的发票号-文件名列表 awk '{ inv_no = substr($0, 4, 4) if (!seen[FILENAME, inv_no]++) { print inv_no, FILENAME } }' *.txt > temp_unique.txt # 找出出现次数>1的发票号(即跨文件重复) awk '{count[$1]++} END {for (i in count) if (count[i]>1) print i}' temp_unique.txt > temp_duplicates.txt # 提取对应重复条目 grep -F -f temp_duplicates.txt temp_unique.txt # 清理临时文件(可选) rm temp_unique.txt temp_duplicates.txt
单条awk命令(高效无临时文件)
追求最高效率时,用单条awk脚本完成所有逻辑,避免临时文件和管道开销,适合处理大量文件:
awk '{ inv_no = substr($0, 4, 4) # 过滤同一文件内的重复发票号 if (!file_inv[FILENAME, inv_no]) { # 记录每个发票号对应的文件条目 inv_files[inv_no] = inv_files[inv_no] inv_no " " FILENAME "\n" file_inv[FILENAME, inv_no] = 1 # 统计发票号出现的文件数 inv_count[inv_no]++ } } END { # 输出所有跨文件重复的发票号及对应文件 for (inv in inv_count) { if (inv_count[inv] > 1) { printf "%s", inv_files[inv] } } }' *.txt
参数调整说明
根据实际发票号的位置修改substr($0, 4, 4):
- 若发票号位于第5-10位,则改为
substr($0, 5, 6)(起始位置为5,长度为6) - 若发票号是固定长度的后缀,也可结合
length()函数调整,比如取最后4位:substr($0, length($0)-3, 4)
内容的提问来源于stack exchange,提问作者Jayadevan
相关产品推荐
相关产品推荐

