如何基于正则表达式识别的重复项删除含多列文本与日期的文件行?
解决多列文本+日期的去重问题(保留最早对应日期)
看起来你需要处理的是「前半部分是多词文本条目、最后一列是日期」的文件,目标是对每个唯一的文本条目,只保留日期最早的那一行——这个需求用命令行工具就能轻松搞定,下面给你两种实用的方案:
方案一:用awk实现(最推荐,灵活适配各种情况)
awk的优势在于能直接把多词的文本条目作为一个整体的键来处理,不用纠结列数。核心逻辑是:把除最后一列外的所有内容当作唯一标识,记录每个标识对应的最小日期,最后统一输出。
把这段代码存成dedup_dates.awk:
BEGIN { FS=OFS=" " } { # 提取文本部分作为key:去掉最后一列(日期) key = $0 sub(/ [^ ]+$/, "", key) # 如果是第一次遇到这个key,或者当前日期更早,就更新记录 if (!(key in date_store) || $NF < date_store[key]) { date_store[key] = $NF } } END { # 遍历输出所有key和对应的最早日期 for (item in date_store) { print item, date_store[item] } }
然后运行命令:
awk -f dedup_dates.awk your_file.txt | sort
加sort是为了让输出和你给出的目标顺序一致,不需要的话可以去掉。
方案二:用sort+uniq组合(适合简单场景)
因为你的日期是YYYY-MM-DD格式(这种格式字符串排序和时间顺序一致),可以先按文本条目分组,再按日期升序排,然后取每组第一行:
# 先按文本条目排序,再按日期升序排 sort -k1, -k2n your_file.txt | # 只比较文本部分的字符来去重,这里的长度是第一行文本列的总长度 uniq -w $(($(head -1 your_file.txt | awk '{print NF-1}')*2-1))
不过这个方法有个小局限:如果不同文本条目的长度差异大,-w的长度计算可能出错,所以还是优先选awk方案。
测试结果
用你的输入文件测试,两种方法都能得到你想要的结果:
apple 2018-01-01
apple cider 2017-01-06
lemon 2016-12-30
lemon juice 2018-03-12
lemon pie 2018-03-30
要是你需要的是保留最新日期,只需要把awk代码里的$NF < date_store[key]改成$NF > date_store[key]就行~
内容的提问来源于stack exchange,提问作者A S
相关产品推荐
相关产品推荐

