在Bash中parsingdate

你将如何parsing一个date在bash中,将单独的字段(年,月,日,时,分,秒)分解成不同的variables?

date格式是: YYYY-MM-DD hh:mm:ss

它必须是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 

这parsing给定的date,并以选定的格式显示它。 你可以随意适应你的需求。

这很简单,只需要将你的破折号和冒号转换成一个空格(不需要改变IFS),然后在一行中使用“read”

 read YMD hms <<< ${date//[-:]/ } 

例如:

 $ date=$(date +'%Y-%m-%d %H:%M:%S') $ read YMD hms <<< ${date//[-: ]/ } $ echo "Y=$Y, m=$m" Y=2009, m=57 
 $ 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 

数组方法可能更好,但这是你特别要求的:

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

纯粹的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 

而不是使用shell脚本,像下面那样将脚本合并到你自己的脚本中:

 a=date +%Y b=date +%S c=date +%H 

a将是b年,c秒将是小时。 等等。

OP的问题的另一个解决scheme是:

 IFS=' -:' read ymdhm s<<<'2014-03-26 16:36:41' 

使用BSD date和GNU date将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即使在非英文语言环境中也能识别WedWed ,但BSD date不会。

将GNUdate和BSDdate之后的秒数转换为date和时间:

 $ 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 

我有一个不同的input时间格式,所以这里是一个更灵活的解决scheme。 在BSD / macOS中转换date的命令是

 date -jf in_format [+out_format] in_date 

格式使用strftime(见man strftime )。

对于给定的input格式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 

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

 $ date_in='2017-05-10 13:40:01' $ format='%Y-%m-%d %H:%M:%S' $ read ymd HMS <<< "$(date -jf "$format" '+%Y %m %d %H %M %S' "$date_in")" $ for var in ymd HMS; 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 

另一个纯粹的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 

你尝试过使用剪切? 像这样:dayofweek = date|cut -d" " -f1