Mac OSX Shell脚本解析ISO 8601日期并添加一秒?

时间:2017-02-16 21:45:24

标签: bash macos shell date-parsing

我试图找出如何使用ISO 8601格式化时间戳来解析文件,添加一秒然后将它们输出到文件中。

我发现的所有示例都没有告诉我如何使用ISO 8601日期/时间字符串。

实施例: 阅读csv次,如:" 2017-02-15T18:47:59" (有些是正确的,有些则不是)

并吐出一个新文件" 2017-02-15T18:48:00"

主要是试图纠正一堆最后有59秒的日期,以达到1秒的标记。

这是我目前的进展:

#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
    # startd=$(date -j -f '%Y%m%d' "$line" +'%Y%m%d'); 
    # echo "$startd";
    startd=$(date -j -u -f "%a %b %d %T %Z %Y" $line) 
    #startd=$(date -j -f '%Y%m%d' "$line" +'%Y%m%d'); 
    echo "$startd";

done < "$1"

任何帮助将不胜感激

2 个答案:

答案 0 :(得分:1)

这可以完成这项工作

perl -MTime::Piece -nlE '$f=q{%Y-%m-%dT%H:%M:%S};$t=Time::Piece->strptime($_,$f)+1;say $t->strftime($f)' < dates.txt

如果dates.txt包含

2017-02-15T18:47:59
2016-02-29T23:59:59
2017-02-28T23:59:59
2015-12-31T23:59:59
2010-10-10T10:10:10

以上产生

2017-02-15T18:48:00
2016-03-01T00:00:00
2017-03-01T00:00:00
2016-01-01T00:00:00
2010-10-10T10:10:11

答案 1 :(得分:1)

jm666's helpful perl answer将比基于shell循环的方法快得多。

也就是说,如果你想让你的bash代码在macOS上运行,并且 BSD date实现,那么这是一个解决方案:

# Define the input date format, which is also used for output.
fmt='%Y-%m-%dT%H:%M:%S'

# Note: -j in all date calls below is needed to suppress setting the 
#       system date.
while IFS= read -r line || [[ -n "$line" ]]; do

    # Parse the line at hand using input format specifier (-f) $fmt, 
    # and output-format specifier (+) '%s', which outputs a Unix epoch
    # timestamp (in seconds).
    ts=$(date -j -f "$fmt" "$line" +%s)

    # See if the seconds-component (%S) is 59...
    if [[ $(date -j -f %s "$ts" +%S) == '59' ]]; then
      # ... and, if so, add 1 second (-v +1S).
      line=$(date -j -f %s -v +1S "$ts" +"$fmt")
    fi

    # Output the possibly adjusted timestamp.
    echo "$line"

done < "$1"

请注意,2017-02-15T18:47:59等输入日期会被解释为本地时间,因为它们不包含时区信息。