web-dev-qa-db-fra.com

Dans un shell unix, comment obtenir la date d'hier dans une variable?

J'ai un script Shell qui fait ce qui suit pour stocker la date du jour actuel dans une variable 'dt':

date "+%a %d/%m/%Y" | read dt
echo ${dt}

Comment pourrais-je obtenir hier date dans une variable?

Essentiellement, ce que j'essaie de faire est d'utiliser grep pour extraire toutes les lignes d'hier d'un fichier journal, car chaque ligne du journal contient la date au format "Lundi 01/02/2010".

Merci beaucoup

37
Chris

Si vous avez Perl disponible (et que votre date ne possède pas de fonctionnalités intéressantes comme yesterday), vous pouvez utiliser:

pax> date
Thu Aug 18 19:29:49 XYZ 2010

pax> dt=$(Perl -e 'use POSIX;print strftime "%d/%m/%Y%",localtime time-86400;')

pax> echo $dt
17/08/2010
12
paxdiablo
dt=$(date --date yesterday "+%a %d/%m/%Y")
echo $dt
64
polemon

Sous Linux, vous pouvez utiliser

date -d "-1 days" +"%a %d/%m/%Y"
43
z1x2

Vous pouvez utiliser la commande GNU date comme indiqué ci-dessous

Obtenir une date dans le passé

Pour obtenir hier et les jours précédents, utilisez le jour de chaîne il y a déjà eu:

date --date = 'hier'

date --date = 'il y a 1 jour'

date --date = '10 day ago '

date --date = '10 week ago '

date --date = '10 months ago '

date --date = '10 year ago '

Obtenir une date dans le futur

Pour obtenir demain et après-demain (demain + N), utilisez Word pour obtenir la date suivante:

date --date = 'demain'

date --date = '1 jour'

date --date = '10 day '

date --date = '10 week '

date --date = '10 mois '

date --date = '10 année '

12
ramit girdhar

Si vous utilisez un Mac, BSD ou autre chose sans l'option --date, vous pouvez utiliser:

date -r `expr \`date +%s\` - 86400` '+%a %d/%m/%Y'

Mise à jour : ou peut-être ...

date -r $((`date +%s` - 86400)) '+%a %d/%m/%Y'
9
DigitalRoss

J'ai un script shell sous Linux et le code suivant a fonctionné pour moi:

#!/bin/bash
yesterday=`TZ=EST+24 date +%Y%m%d` # Yesterday is a variable
mkdir $yesterday # creates a directory with  YYYYMMDD format
5
jujuBee

Vous avez au moins 2 options

  1. Utilisez Perl:

    Perl -e '@T=localtime(time-86400);printf("%02d/%02d/%02d",$T[4]+1,$T[3],$T[5]+1900)'
    
  2. Installez la date GNU (elle est dans le paquet sh_utils si je me souviens bien)

    date --date yesterday "+%a %d/%m/%Y" | read dt
    echo ${dt}
    
  3. Vous ne savez pas si cela fonctionne, mais vous pourrez peut-être utiliser un fuseau horaire négatif. Si vous utilisez un fuseau horaire qui se trouve 24 heures avant votre fuseau horaire actuel, vous pouvez simplement utiliser date.

4
Wolph

Essayez la méthode suivante:

dt=`case "$OSTYPE" in darwin*) date -v-1d "+%s"; ;; *) date -d "1 days ago" "+%s"; esac`
echo $dt

Cela fonctionne sous Linux et OSX.

3
kenorb

Voici un script ksh pour calculer la date précédente du premier argument, testé sur Solaris 10 .

#!/bin/ksh
 sep=""
 today=$(date '+%Y%m%d')
 today=${1:-today}
 ty=`echo $today|cut -b1-4` # today year
 tm=`echo $today|cut -b5-6` # today month
 td=`echo $today|cut -b7-8` # today day
 yy=0 # yesterday year
 ym=0 # yesterday month
 yd=0 # yesterday day

 if [ td -gt 1 ];
 then
         # today is not first of month
         let yy=ty       # same year
         let ym=tm       # same month
         let yd=td-1     # previous day
 else
         # today is first of month
         if [ tm -gt 1 ];
         then
                 # today is not first of year
                 let yy=ty       # same year
                 let ym=tm-1     # previous month
                 if [ ym -eq 1 -o ym -eq 3 -o ym -eq 5 -o ym -eq 7 -o ym -eq 8 -o ym -     eq 10 -o ym -eq 12 ];
                 then
                         let yd=31
                 fi
                 if [ ym -eq 4 -o ym -eq 6 -o ym -eq 9 -o ym -eq 11 ];
                 then
                         let yd=30
                 fi
                 if [ ym -eq 2 ];
                 then
                         # shit... :)
                         if [ ty%4 -eq 0 ];
                         then
                                 if [ ty%100 -eq 0 ];
                                 then
                                         if [ ty%400 -eq 0 ];
                                         then
                                         #echo divisible by 4, by 100, by 400
                                                 leap=1 
                                         else
                                         #echo divisible by 4, by 100, not by 400
                                                 leap=0
                                         fi
                                 else
                                         #echo divisible by 4, not by 100
                                         leap=1 
                                 fi
                         else
                                 #echo not divisible by 4
                                 leap=0 # not divisible by four
                         fi
                         let yd=28+leap
                 fi
         else
                 # today is first of year
                 # yesterday was 31-12-yy
                 let yy=ty-1     # previous year
                 let ym=12
                 let yd=31
         fi
 fi
 printf "%4d${sep}%02d${sep}%02d\n" $yy $ym $yd

Des tests

bin$ for date in 20110902 20110901 20110812 20110801 20110301 20100301 20080301 21000301 20000301 20000101 ; do yesterday $date; done
20110901
20110831
20110811
20110731
20110228
20100228
20080229
21000228
20000229
19991231

Merci à tous pour l’aide fournie, mais depuis que je suis sur HP-UX (après tout: plus vous payez, moins vous obtenez de fonctionnalités ...), j’ai dû faire appel à Perl:

Perl -e '@T=localtime(time-86400);printf("%02d/%02d/%04d",$T[3],$T[4]+1,$T[5]+1900)' | read dt
2
Chris

Si Tcl est installé sur votre installation HP-UX, vous constaterez peut-être que son calcul arithmétique des dates est très lisible (malheureusement, le shell Tcl n'a pas d'option "-e" agréable comme Perl):

dt=$(echo 'puts [clock format [clock scan yesterday] -format "%a %d/%m/%Y"]' | tclsh)
echo "yesterday was $dt"

Cela gèrera toute la journée.

2
glenn jackman
$var=$TZ;
TZ=$TZ+24;
date;
TZ=$var;

Vous obtiendrez hier sous AIX et réinitialiserez la variable TZ à son origine.

2
santymano

ksh93:

dt=${ printf "%(%a %d/%m/%Y)T" yesterday; }

ou:

dt=$(printf "%(%a %d/%m/%Y)T" yesterday)

Le premier s'exécute dans le même processus, le second dans un sous-shell.

2
danlei

Si vous avez accès à python, il s'agit d'un utilitaire qui obtiendra la valeur de date yyyy-mm-dd pour toute variable n jours auparavant:

function get_n_days_ago {
  local days=$1
  python -c "import datetime; print (datetime.date.today() - datetime.timedelta(${days})).isoformat()"
}

# today is 2014-08-24

$ get_n_days_ago 1
2014-08-23

$ get_n_days_ago 2
2014-08-22
2
wuster

Si vous ne disposez pas d'une version de date compatible avec --yesterday et que vous ne souhaitez pas utiliser Perl, vous pouvez utiliser ce script ksh très pratique. Par défaut, il renvoie la date d'hier, mais vous pouvez lui attribuer un nombre et lui indiquer la date de plusieurs jours. Cela commence à ralentir un peu si vous regardez loin dans le passé. Il y a 100 000 jours, il était 1/30/1738, bien que mon système a pris 28 secondes pour comprendre cela.

    #! /bin/ksh -p

    t=`date +%j`
    ago=$1
    ago=${ago:=1} # in days
    y=`date +%Y`

    function build_year {
            set -A j X $( for m in 01 02 03 04 05 06 07 08 09 10 11 12
                    {
                            cal $m $y | sed -e '1,2d' -e 's/^/ /' -e "s/ \([0-9]\)/ $m\/\1/g"
                    } )
            yeardays=$(( ${#j[*]} - 1 ))
    }

    build_year

    until [ $ago -lt $t ]
    do
            (( y=y-1 ))
            build_year
            (( ago = ago - t ))
            t=$yeardays
    done

    print ${j[$(( t - ago ))]}/$y
2
Ken Beer

Bien que toutes les bonnes réponses, malheureusement, aucune d'entre elles n'a fonctionné pour moi. J'ai donc dû écrire quelque chose de la vieille école. (J'étais sur un système d'exploitation Linux minimal)

$ date -d @$( echo $(( $(date +%s)-$((60*60*24)) )) )

Vous pouvez combiner ceci avec le formatage habituel de la date. Par exemple. 

$ date -d @$( echo $(( $(date +%s)-$((60*60*24)) )) ) +%Y-%m-%d

Explication: Prenez la date en termes de secondes epoc (option -d), auxquelles vous auriez soustrait une seconde équivalente à un jour. Cela vous donnera la date précisément un jour de retour.

2
Gautam

Pour HP-UX, seule la commande ci-dessous a fonctionné pour moi:

TZ = date aaa24 +% Y% m% d

vous pouvez l'utiliser comme:

ydate = `TZ = aaa24 date +% Y% m% d`

echo $ ydate

1
Anvesh