Date d’parsing dans Bash

Comment parsingriez-vous une date dans bash, avec des champs séparés (années, mois, jours, heures, minutes, secondes) en différentes variables?

Le format de la date est: YYYY-MM-DD hh:mm:ss

Est-ce que ça doit être bash? Vous pouvez utiliser le binary GNU coreutils /bin/date pour plusieurs transformations:

  $ 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 

Cela parsing la date donnée et l’affiche dans le format choisi. Vous pouvez adapter cela à votre guise.

C’est simple, convertissez simplement vos tirets et deux points en un espace (inutile de changer IFS) et utilisez “read” sur une seule ligne:

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

Par exemple:

 $ 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 

La méthode du tableau est peut-être meilleure, mais c’est ce que vous demandiez spécifiquement:

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

J’avais un format de temps de saisie différent, alors voici une solution plus flexible. La commande pour convertir les dates en BSD / macOS est

 date -jf in_format [+out_format] in_date 

où les formats utilisent strftime (voir man strftime ).

Pour le format d’entrée donné 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 

Pour les lire dans des variables distinctes, je prends l’idée de NVRAM, mais vous permet d’utiliser n’importe quel format 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 

Dans mon cas, je voulais convertir entre les fuseaux horaires (voir votre /usr/share/zoneinfo pour les noms de zone):

 $ 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 

au lieu d’utiliser le script shell, incorporez-le dans votre script comme ci-dessous, où que vous ayez besoin:

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

a sera l’année b sera les secondes c sera les heures. etc.

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 

Une autre solution au problème du PO:

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

Conversion d'une date à un autre format avec date BSD et date GNU:

 $ 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 

La date GNU reconnaît Wed et Mar même dans les pays non anglophones, mais pas la date BSD.

Conversion de secondes depuis l’époque en une date et une heure avec la date GNU et la date BSD:

 $ gdate -d @1234567890 '+%F %T' 2009-02-14 01:31:30 $ date -r 1234567890 '+%F %T' 2009-02-14 01:31:30 

Conversion de secondes en heures, minutes et secondes avec un shell POSIX, POSIX awk , une date GNU et une date BSD:

 $ 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 

Conversion de secondes en jours, heures, minutes et secondes:

 $ t=12345678 $ printf '%d:%02d:%02d:%02d\n' $((t/86400)) $((t/3600%24)) $((t/60%60)) $((t%60)) 142:21:21:18 

une autre bash pure

 $ 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 

avez-vous essayé d’utiliser la coupe? quelque chose comme ça: dayofweek = date|cut -d" " -f1