MacOS Bash中日期格式转换问题求助
问题描述
我正在学习Bash,目前有一批来自不受控合并数据源的日期列表,格式如下:
1 July 2023 3 July 2023 10 July 2023 August 1, 2023 August 8, 2023 July 1, 2023 July 3, 2023 July 9, 2023 July 10, 2023
我希望将这些日期统一转换为2023-07-01这样的YYYY-MM-DD格式。
我目前的做法是切割变量并重新排序:
# Grab Date From Filename event_date_year=$(cut -d ' ' -f 6 <<<"$event_filename") event_date_month=$(cut -d ' ' -f 4 <<<"$event_filename") event_date_day="0"$(cut -d ' ' -f 5 <<<"$event_filename") # Trim unneeded zero event_date_day=${event_date_day:-2} event_date=$event_date_year"-"$event_date_month"-"$event_date_day
接下来我还需要遍历月份列表将其替换为数字,并且要检测另一种日期格式进行处理。我觉得肯定有更简便的方法,但目前毫无头绪。我尝试过使用date命令,但它似乎无法识别输入的日期格式。请问有什么解决方案建议吗?
解决方案
方案1:借助GNU date快速处理
GNU版本的date支持灵活的日期解析,只需要先清理掉日期中的逗号,就能自动兼容两种输入格式:
while read -r date_str; do # 移除日期里的逗号 cleaned_date=${date_str//,/} # 用date命令转换格式,失败则跳过(可根据需求添加错误处理) date -d "$cleaned_date" +%Y-%m-%d 2>/dev/null done < 你的日期文件.txt
这个脚本会自动识别DD Month YYYY和Month DD YYYY两种格式,直接输出标准的YYYY-MM-DD日期。
方案2:用awk实现跨平台兼容
如果你的环境没有GNU date(比如macOS默认的date工具),用awk写个脚本更稳妥,提前定义月份映射,然后匹配两种格式处理:
BEGIN { # 初始化月份到两位数字的映射 split("January February March April May June July August September October November December", months_arr, " ") for (i=1; i<=12; i++) { month_map[months_arr[i]] = sprintf("%02d", i) } } # 匹配 DD Month YYYY 格式 $2 in month_map && NF == 3 { printf "%s-%s-%02d\n", $3, month_map[$2], $1 next } # 匹配 Month DD, YYYY 格式 $1 in month_map && NF == 3 { # 去掉日期中的逗号 gsub(",", "", $2) printf "%s-%s-%02d\n", $3, month_map[$1], $2 }
将上述代码保存为date_convert.awk,然后执行:
awk -f date_convert.awk 你的日期文件.txt
就能直接得到统一格式的日期输出。
补充说明
你之前的切割逻辑完全依赖日期在文件名中的固定字段位置,一旦文件名结构变化(比如日期位置偏移),代码就会失效。上面的两种方法都是直接针对日期字符串本身解析,灵活性和可靠性更高。如果是从文件名提取日期,建议先把日期部分从文件名中剥离出来,再用上述方法转换。
内容的提问来源于stack exchange,提问作者OneHydrogenLoose
相关产品推荐
相关产品推荐

