在Bash中解析日期

Ste*_*eve 54 bash parsing date

你如何解析bash中的日期,将不同的字段(年,月,日,小时,分钟,秒)分成不同的变量?

日期格式为: YYYY-MM-DD hh:mm:ss

Dir*_*tel 64

它必须是bash吗?您可以使用GNU coreutils /bin/date二进制文件进行许多转换:

 $ date --date="2009-01-02 03:04:05" "+%d %B of %Y at %H:%M and %S seconds"
 02 January of 2009 at 03:04 and 05 seconds
Run Code Online (Sandbox Code Playgroud)

这将解析给定日期并以所选格式显示.您可以根据自己的需要随意调整.

  • `--date` /`-d`是一个GNU扩展.POSIX只为`date`指定一个选项(`-u`).您可以在BSD/OS中使用`date -jf'%F%T''2009-01-02 03:04:05''+%d%B%Y在%H:%M和%S秒'` X日期. (13认同)
  • 这是Linux扩展吗?FreeBSD或Mac OSX似乎都不支持它. (9认同)
  • 这是简单的旧 GNU 日期:$ date --version date (GNU coreutils) 7.4 版权所有 (C) 2009 Free Software Foundation, Inc. 许可证 GPLv3+:GNU GPL 版本 3 或更高版本 <http://gnu.org/licenses/gpl。 html>。这是免费软件:您可以自由更改和重新分发它。在法律允许的范围内,不提供任何保证。由大卫麦肯齐撰写。 (2认同)
  • `date --date="\`date\`"` 为我工作并产生与日期相同的输出。版本是`date (GNU coreutils) 8.20`。您使用哪个“日期”? (2认同)

NVR*_*RAM 30

这很简单,只需将破折号和冒号转换为空格(无需更改IFS)并在一行中使用"read"all:

read Y M D h m s <<< ${date//[-:]/ }
Run Code Online (Sandbox Code Playgroud)

例如:

$ date=$(date +'%Y-%m-%d %H:%M:%S')
$ read Y M D h m s <<< ${date//[-: ]/ }
$ echo "Y=$Y, m=$m"
Y=2009, m=57
Run Code Online (Sandbox Code Playgroud)


Cha*_*ert 16

我有一个不同的输入时间格式,所以这是一个更灵活的解决方案.

在BSD/macOS中转换日期

date -jf in_format [+out_format] in_date
Run Code Online (Sandbox Code Playgroud)

格式使用strftime的地方(参见参考资料man strftime).

对于给定的输入格式YYYY-MM-DD hh:mm:ss:

$ date -jf '%Y-%m-%d %H:%M:%S' '2017-05-10 13:40:01'
Wed May 10 13:40:01 PDT 2017
Run Code Online (Sandbox Code Playgroud)

要将它们读入单独的变量,我正在考虑NVRAM的想法,但允许您使用任何strftime格式:

$ date_in='2017-05-10 13:40:01'

$ format='%Y-%m-%d %H:%M:%S'

$ read -r y m d H M S <<< "$(date -jf "$format" '+%Y %m %d %H %M %S' "$date_in")"

$ for var in y m d H M S; do echo "$var=${!var}"; done
y=2017
m=05
d=10
H=13
M=40
S=01
Run Code Online (Sandbox Code Playgroud)

(在脚本中,始终使用read -r.)

就我而言,我想在时区之间进行转换(请参阅您的/usr/share/zoneinfo目录以获取区域名称):

$ format=%Y-%m-%dT%H:%M:%S%z

$ TZ=UTC date -jf $format +$format 2017-05-10T02:40:01+0200
2017-05-10T00:40:01+0000

$ TZ=America/Los_Angeles date -jf $format +$format 2017-05-10T02:40:01+0200
2017-05-09T17:40:01-0700
Run Code Online (Sandbox Code Playgroud)

在GNU/Linux中转换日期

在Mac上,你可以安装GNU版本dategdate使用brew install coreutils.

date [+out_format] -d in_date
Run Code Online (Sandbox Code Playgroud)

out_format使用strftime的地方(参见参考资料man strftime).

在GNU coreutils' date命令中,没有办法显式设置输入格式,因为它试图自己找出输入格式,而东西通常只是起作用.(有关详细信息,您可以阅读coreutils上的手册:日期输入格式.)

例如:

$ date '+%Y %m %d %H %M %S' -d '2017-05-10 13:40:01'
2017 05 10 13 40 01
Run Code Online (Sandbox Code Playgroud)

要将它们读入单独的变量,请通过将括号中的命令替换为GNU版本来修改Mac部分中的命令.

要在时区之间进行转换(请参阅您的/usr/share/zoneinfo目录以获取区域名称),您可以TZ="America/Los_Angeles"在输入字符串中指定.注意"区域名称周围的文字字符和in_date之前的空格字符:

TZ=out_tz date [+out_format] 'TZ="in_tz" 'in_date
Run Code Online (Sandbox Code Playgroud)

例如:

$ format='%Y-%m-%d %H:%M:%S%z'

$ TZ=America/Los_Angeles date +"$format" -d 'TZ="UTC" 2017-05-10 02:40:01'
2017-05-09 19:40:01-0700

$ TZ=UTC date +"$format" -d 'TZ="America/Los_Angeles" 2017-05-09 19:40:01'
2017-05-10 02:40:01+0000
Run Code Online (Sandbox Code Playgroud)

GNU日期还了解时区的小时偏移:

$ TZ=UTC date +"$format" -d '2017-05-09 19:40:01-0700'
2017-05-10 02:40:01+0000
Run Code Online (Sandbox Code Playgroud)


Dig*_*oss 7

$ t='2009-12-03 12:38:15'
$ a=(`echo $t | sed -e 's/[:-]/ /g'`)
$ echo ${a[*]}
2009 12 03 12 38 15
$ echo ${a[3]}
12
Run Code Online (Sandbox Code Playgroud)


Ste*_*ker 5

数组方法也许更好,但这是您专门要求的:

IFS=" :-"
read year month day hour minute second < <(echo "YYYY-MM-DD hh:mm:ss")
Run Code Online (Sandbox Code Playgroud)