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