You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

sed命令转换mm/dd/yyyy至DD-MMM-YYYY格式出错求助

问题描述

需要将字符串06/08/2023 06:30:11 06/08/2023 06:30:19中的mm/dd/yyyy格式日期转换为DD-MMM-YYYY格式(预期结果:08-JUN-2023 06:30:11 08-JUN-2023 06:30:19),但执行以下sed命令后得到错误日期01-Feb-0003:

echo "06/08/2023 06:30:11 06/08/2023 06:30:19" | sed -E 's#([0-9]{2})/([0-9]{2})/([0-9]{4})#'"$(echo '\2/\1/\3' | xargs -I{} date -d {} +'%d-%^b-%Y')"#g
错误原因

核心问题是命令替换的执行时机:

  • Shell会优先解析$(...)部分,此时sed的捕获组\2、\1、\3还未被sed匹配替换,只是单纯的字面字符串。
  • echo '\2/\1/\3'输出的是\2/\1/\3,传给date -d后,date会忽略非数字字符,将其解析为2/1/3(即0003年2月1日),因此生成错误的01-Feb-0003。
  • 最终sed拿到这个错误结果,将所有匹配到的日期全部替换成它,导致整体输出错误。
正确解决方案

方案1:使用awk(跨平台兼容性好)

awk可直接处理捕获组,并通过strftime函数转换日期格式(需GNU awk或支持该函数的awk版本):

echo "06/08/2023 06:30:11 06/08/2023 06:30:19" | awk '{
    for (i=1; i<=NF; i++) {
        if ($i ~ /^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/) {
            split($i, d, "/");
            mktime(d[3]" "d[1]" "d[2]" 0 0 0");
            $i = strftime("%d-%^b-%Y");
        }
    }
    print $0
}'

输出结果:

08-JUN-2023 06:30:11 08-JUN-2023 06:30:19

方案2:使用GNU sed的e命令(仅适用于GNU sed)

GNU sed支持e标志,可将替换后的内容作为shell命令执行,并用输出替换原匹配内容:

echo "06/08/2023 06:30:11 06/08/2023 06:30:19" | sed -E 's#([0-9]{2})/([0-9]{2})/([0-9]{4})#echo "\2/\1/\3" | xargs -I{} date -d {} +"%d-%^b-%Y"#ge'
  • g表示全局替换,e表示执行替换生成的shell命令,用命令输出替换原匹配的日期字符串。

方案3:使用Shell循环处理(适合简单场景)

input="06/08/2023 06:30:11 06/08/2023 06:30:19"
output=""
for word in $input; do
    if [[ $word =~ ^([0-9]{2})/([0-9]{2})/([0-9]{4})$ ]]; then
        new_date=$(date -d "${BASH_REMATCH[2]}/${BASH_REMATCH[1]}/${BASH_REMATCH[3]}" +'%d-%^b-%Y')
        output="$output $new_date"
    else
        output="$output $word"
    fi
done
echo "${output# }"

内容的提问来源于stack exchange,提问作者Mahesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 07:17:31