【问题标题】:unix yyyymmddhhmmss format conversion to specific date formatunix yyyymmddhhmmss 格式转换为特定日期格式
【发布时间】:2019-02-13 17:34:15
【问题描述】:

有一个 bash 脚本正在运行,该脚本输出附加时间的文件夹名称 logs_debug_20190213043348。我需要能够将日期提取为可读格式 yyyy.mm.dd.hh.mm.ss,并且还可以转换为 GMT 时区。我正在使用以下方法进行提取。

回显“${文件夹##*_}”| awk '{ print substr($0,1,4)"."substr($0,5,2)"."substr($0,7,2)"."substr($0,9,6)}'

有没有更好的方法来打印输出而无需编写复杂的 shell 脚本?

【问题讨论】:

    标签: date unix


    【解决方案1】:

    内部字符串转换功能太有限,所以需要的时候使用sedtr

    ## The "readable" format yyyy.mm.dd.hh.mm.ss isn’t understood by date. 
    ## yyyy-mm-dd hh:mm:ss is. So we first produce the latter.
    
    # Note how to extract the last 14 characters of ${folder} and that, since
    # we know (or should have checked somewhere else) that they are all digits,
    # we match them with a simple dot instead of the more precise but less
    # readable [0-9] or [[:digit:]]
    # -E selects regexp dialect where grouping is done with simple () with no
    # backslashes.
    d="$(sed -Ee's/(....)(..)(..)(..)(..)(..)/\1-\2-\3 \4:\5:\6/'<<<"${folder:(-14)}")"
    
    # Print the UTF date (for Linux and other systems with GNU date)
    date -u -d "$d"
    
    # Convert to your preferred "readable" format  
    # echo "${d//[: -]/.}" would have the same effect, avoiding tr
    tr ': -' '.'<<<"$d"
    

    对于带有 BSD date 的系统(尤其是 MacOS),请使用

    date -juf'%Y-%m-%d %H:%M:%S' "$d"
    

    而不是上面给出的date 命令。当然,在这种情况下,最简单的方法是:

    # Convert to readable
    d="$(sed -Ee's/(....)(..)(..)(..)(..)(..)/\1.\2.\3.\4.\5.\6/'<<<"${folder:(-14)}")"
    # Convert to UTF
    date -juf'%Y.%m.%d.%H.%M.%S' "$d"
    

    【讨论】:

    • echo $d 2019-02-13 04:33:48 $ date -u -d "$d" ---> 这行没有按预期工作,给我一个使用信息。用法:日期 [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+格式]
    • @neelmeg 抱歉,我应该提到我使用 GNU date。您可能使用的是 BSD 系统(MacOS?)。将编辑答案。
    • 编辑以涵盖 BSD 案例。
    • 退出,同时运行日期命令: date -juf'%Y.%m.%d.%H.%M.%s' "$d" Thu Jan 1 00:00: 42 UTC 1970
    • 抱歉,错字:%s 应该是 %S(在这两个地方)。在 Mac 上更正和测试。
    【解决方案2】:

    这是一个满足您需求的管道。看起来肯定不简单,但是把每一个组件都拿出来就可以理解了:

    echo "20190213043348" | \
    sed -e 's/\([[:digit:]]\{4\}\)\([[:digit:]]\{2\}\)\([[:digit:]]\{2\}\)\([[:digit:]]\{2\}\)\([[:digit:]]\{2\}\)\([[:digit:]]\{2\}\)/\1-\2-\3 \4:\5:\6/' | \
    xargs -d '\n' date -d | \
    xargs -d '\n' date -u -d
    

    第一行只是打印日期字符串,以便 sed 对其进行格式化(以便可以轻松修改它以适应您在字符串中传递的方式)。

    带有sed 的第二行是将字符串从您提供的格式转换为类似这样的格式,可以由date 解析:2019-02-13 04:33:48

    然后,我们使用xargs 将日期传递给date,并使用运行脚本的设备的时区(在我的例子中为CST)格式化它:Wed Feb 13 04:33:48 CST 2019

    最后一行将第一次调用 date 给出的日期字符串转换为 UTC 时间,而不是停留在本地时间:Wed Feb 13 10:33:48 UTC 2019

    如果您希望它采用不同的格式,您可以使用+FORMAT 参数修改date 的最终调用。

    【讨论】:

    • 数字匹配模式[0-9][[:digit:]]稍微简洁一些。
    • sed 模式's/.*_\(....)\(..\)\(..\)\(..\)\(..\)\(..\)$/\1-\2-\3 \4:\5:\6/' 更短。
    猜你喜欢
    • 2014-06-17
    • 1970-01-01
    • 2017-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    相关资源
    最近更新 更多