如何在Bash中根据文件名提取对应数据日期的最新日志行?
处理重复上报日志:保留最新CSV文件对应数据
服务器日志存在重复上报情况,需根据CSV文件名的时间戳判断最新文件,保留对应数据日期的日志行。以下是grep得到的简化数据示例:
... 20150630-201427.csv:20150630,CFIIASU,233,96.21786,0.44644, 20150630-201427.csv:20150630,CFIIASU_AU,65,90.71109,0.28569 20150630-201427.csv:20150630,CFIIASU_CN,68,102.19569,0.10692 20150630-201427.csv:20150630,CFIIASU_ID,37,98.02484,0.27775 20150630-201427.csv:20150630,CFIIASU_KR,39,98.42257,0.83055 20150630-201427.csv:20150630,CFIIASU_TH,24,99.94482,0.20743 20150701-151654.csv:20150630,CFIIASU,233,96.21450,0.44294 20150701-151654.csv:20150630,CFIIASU_AU,65,90.71109,0.28569 20150701-151654.csv:20150630,CFIIASU_CN,68,102.16538,0.07723 20150701-151654.csv:20150630,CFIIASU_ID,37,98.02484,0.27775 20150701-151654.csv:20150630,CFIIASU_KR,39,98.42257,0.83055 20150701-151654.csv:20150630,CFIIASU_TH,24,99.94482,0.20743 ...
数据说明
- 示例数据来自
20150630-201427.csv和20150701-151654.csv,每行包含日期、数据名称、data_column1、data_column2、data_column3列 - 不同文件中存在相同日期(如
20150630)和相同数据名称的行,但data_column2、data_column3数值有差异,需保留最新文件中的对应行
期望结果
20150701-151654.csv:20150630,CFIIASU,233,96.21450,0.44294 20150701-151654.csv:20150630,CFIIASU_AU,65,90.71109,0.28569 20150701-151654.csv:20150630,CFIIASU_CN,68,102.16538,0.07723 20150701-151654.csv:20150630,CFIIASU_ID,37,98.02484,0.27775 20150701-151654.csv:20150630,CFIIASU_KR,39,98.42257,0.83055 20150701-151654.csv:20150630,CFIIASU_TH,24,99.94482,0.20743
解决方案
方法1:用awk高效处理(适合大量文件)
通过awk按「日期+数据名称」作为唯一键,记录每个键对应的最新文件行,最后输出所有最新记录:
ls -v *.csv | xargs awk '{ split(FILENAME, fn, /[-.]/) file_time = fn[1] fn[2] split($0, line, /:/) split(line[2], fields, /,/) key = fields[1] "," fields[2] if (!(key in latest) || file_time > latest[key]["time"]) { latest[key]["time"] = file_time latest[key]["line"] = $0 } } END { for (key in latest) { print latest[key]["line"] } }'
ls -v:按文件名的自然时间顺序排序(文件名的YYYYMMDD-HHMMSS格式适配该排序逻辑)- awk逻辑:以「日期+数据名称」作为唯一标识,仅保留来自最新文件的对应行
方法2:分步骤处理(逻辑更直观)
先提取所有不重复的数据日期,再逐个日期找到对应最新文件并提取行:
# 提取所有不重复的8位数据日期 grep -oP '^.*csv:(\d{8}),' *.csv | cut -d',' -f1 | cut -d':' -f2 | sort -u > dates.txt # 遍历每个日期,提取对应最新文件的行 while read date; do latest_file=$(grep -l "$date," *.csv | sort -V | tail -n1) grep "$date," "$latest_file" done < dates.txt
- 第一步:从所有行中提取出现过的8位数据日期并去重
- 第二步:对每个日期,找到包含它的所有CSV文件,按时间排序取最新的一个,再提取该文件中对应日期的行
内容的提问来源于stack exchange,提问作者Tilei Liu
相关产品推荐
相关产品推荐

