如何用bash解析日期,将不同的字段(年,月,日,小时,分钟,秒)分成不同的变量?
日期格式为:YYYY-MM-DD hh:mm:ss
答案 0 :(得分:63)
它必须是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
解析给定日期并以所选格式显示。您可以随意根据自己的需要进行调整。
答案 1 :(得分:28)
这很简单,只需将你的破折号和冒号转换为空格(无需更改IFS)并在一行中使用'read':
read Y M D h m s <<< ${date//[-:]/ }
例如:
$ 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
答案 2 :(得分:14)
我有不同的输入时间格式,因此这里有一个更灵活的解决方案。
date -jf in_format [+out_format] in_date
格式使用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
要将它们读入单独的变量,我采用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
在我的情况下,我想在时区之间进行转换(请参阅/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
在Mac上,您可以使用
date
将gdate
的GNU版本安装为brew install coreutils
。
date [+out_format] -d in_date
out_format使用strftime(参见man strftime
)。
在GNU coreutils&#39; date
命令,没有办法显式设置输入格式,因为它试图自己找出输入格式,而东西通常只是起作用。 (有关详细信息,请阅读coreutils: Date input formats上的手册。)
例如:
$ date '+%Y %m %d %H %M %S' -d '2017-05-10 13:40:01'
2017 05 10 13 40 01
要将它们读入单独的变量,请通过将括号中的命令替换为GNU版本来修改Mac部分中的命令。
要在时区之间进行转换(请参阅/usr/share/zoneinfo
目录中的区域名称),您可以在输入字符串中指定TZ="America/Los_Angeles"
。注意区域名称周围的文字"
字符和in_date之前的空格字符:
TZ=out_tz date [+out_format] 'TZ="in_tz" 'in_date
例如:
$ 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
GNU日期还了解时区的小时偏移量:
$ TZ=UTC date +"$format" -d '2017-05-09 19:40:01-0700'
2017-05-10 02:40:01+0000
答案 3 :(得分: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
答案 4 :(得分:5)
数组方法可能更好,但这是你特别要求的:
IFS=" :-"
read year month day hour minute second < <(echo "YYYY-MM-DD hh:mm:ss")
答案 5 :(得分:3)
Pure Bash:
date="2009-12-03 15:35:11"
saveIFS="$IFS"
IFS="- :"
date=($date)
IFS="$saveIFS"
for field in "${date[@]}"
do
echo $field
done
2009
12
03
15
35
11
答案 6 :(得分:2)
而不是使用shell脚本,无论你需要什么,都可以在脚本本身中加入:
a=date +%Y
b=date +%S
c=date +%H
将是一年 b将是秒 c将是几个小时。等等。
答案 7 :(得分:2)
OP问题的另一个解决方案:
IFS=' -:' read y m d h m s<<<'2014-03-26 16:36:41'
使用BSD date
和GNU date
将日期转换为另一种格式:
$ LC_ALL=C date -jf '%a %b %e %H:%M:%S %Z %Y' 'Wed Mar 26 16:36:41 EET 2014' +%F\ %T
2014-03-26 16:36:41
$ gdate -d 'Wed Mar 26 16:36:41 EET 2014' +%F\ %T
2014-03-26 16:36:41
即使在非英语语言环境中,GNU date
也会识别Wed
和Mar
,但BSD date
则不会。
将自纪元以来的秒数转换为GNU日期和BSD日期的日期和时间:
$ gdate -d @1234567890 '+%F %T'
2009-02-14 01:31:30
$ date -r 1234567890 '+%F %T'
2009-02-14 01:31:30
使用POSIX shell,POSIX awk
,GNU date
和BSD date
将秒转换为小时,分钟和秒:
$ s=12345;printf '%02d:%02d:%02d\n' $((s/3600)) $((s%3600/60)) $((s%60))
05:25:45
$ echo 12345|awk '{printf "%02d:%02d:%02d\n",$0/3600,$0%3600/60,$0%60}'
05:25:45
$ gdate -d @12345 +%T
05:25:45
$ date -r 12345 +%T
05:25:45
将秒数转换为天,小时,分钟和秒:
$ t=12345678
$ printf '%d:%02d:%02d:%02d\n' $((t/86400)) $((t/3600%24)) $((t/60%60)) $((t%60))
142:21:21:18
答案 8 :(得分:1)
另一个纯粹的bash
$ d="2009-12-03 15:35:11"
$ d=${d//[- :]/|}
$ IFS="|"
$ set -- $d
$ echo $1
2009
$ echo $2
12
$ echo $@
2009 12 03 15 35 11
答案 9 :(得分:0)
date|cut -d" " -f1