如何在Bash中按日期子串对数组排序并保存结果到文件
Bash多行日志数组按时间排序并落地方案
你的日志数组元素包含内嵌换行,排序时不能直接用换行作为条目分隔符,否则会把单条多行日志拆成多个独立条目打乱结构。以下是可直接运行的实现:
# 原始日志数组定义 logs=( "01.05.2022 01:01:35 [ERROR] test error message" "01.05.2022 00:00:55 [SUCCESS] test success message" "02.05.2022 00:00:35 [ERROR] test error message" "01.05.2022 00:05:00 [WARNING] test warning message" ) # 按日期时间升序排序,结果存入新数组 # 用NUL字符作为条目分隔符,避免拆分多行日志;按年→月→日→时间的优先级排序,避免DD.MM.YYYY格式字符串序跨月/跨年错乱 mapfile -d '' sorted_logs < <( printf '%s\0' "${logs[@]}" | sort -z -k1.7,1.10 -k1.4,1.5 -k1.1,1.2 -k1.12,1.19 )
结果保存到文件的两种方式
- 存为可直接被Bash导入的数组格式:
# 写入数组结构 echo 'logs=(' > sorted_logs.txt for item in "${sorted_logs[@]}"; do # 自动转义内嵌换行、引号等特殊字符 printf ' %q\n' "$item" done >> sorted_logs.txt echo ')' >> sorted_logs.txt
后续需要用的时候直接执行source sorted_logs.txt就能加载排序后的数组。
- 存为纯文本日志格式(条目间空一行分隔,方便阅读):
for item in "${sorted_logs[@]}"; do printf '%s\n\n' "$item" done > sorted_logs_plain.txt
参数说明
printf '%s\0' "${logs[@]}":遍历数组输出每个元素,元素尾部追加NUL分隔符,不受元素内换行、空格影响sort -z:指定sort按NUL识别条目边界,适配多行日志场景-k排序键规则:针对每个条目开头固定格式的DD.MM.YYYY HH:MM:SS时间串,按年(第7-10位)、月(第4-5位)、日(第1-2位)、时间(第12-19位)的优先级排序,完全符合时间先后逻辑,不会出现跨月、跨年排序错误mapfile -d '' sorted_logs:读取NUL分隔的排序结果,存入新数组,完整保留每个日志条目的内嵌换行格式
注意:该方案依赖Bash 4.0+版本、GNU coreutils提供的sort工具,主流Linux发行版默认满足依赖;macOS环境需先通过homebrew安装coreutils后使用。
内容的提问来源于stack exchange,提问作者Uolary
相关产品推荐
相关产品推荐

