views:

108

answers:

7

Hi, I've got a shell script which does the following to store the current day's date in a variable 'dt':

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

How would i go about getting yesterdays date into a variable?

Basically what i'm trying to achieve is to use grep to pull all of yesterday's lines from a log file, since each line in the log contains the date in "Mon 01/02/2010" format.

Thanks a lot

+2  A: 

You have atleast 2 options

  1. Use perl:

    perl -e '@T=localtime(time-86400);printf("%02d/%02d/%02d",$T[4]+1,$T[3],$T[5]+1900)'
    
  2. Install GNU date (it's in the sh_utils package if I remember correctly)

    date --date yesterday "+%a %d/%m/%Y" | read dt
    echo ${dt}
    
  3. Not sure if this works, but you might be able to use a negative timezone. If you use a timezone that's 24 hours before your current timezone than you can simply use date.

WoLpH
Sorry! I'm on HP-UX!
Chris
@Chris: I assumed it wouldn't be a GNU compatible `date` but since you didn't specify the Unix variant I simply guessed ;) With `HP-UX` your options are a little more limited, `date` doesn't have these options so `Perl` might be the best option.
WoLpH
Not that it matters but you don't need to add `1900` to the year if you're then going to `%100` the result :-)
paxdiablo
@paxdiablo: fair point, Perl is obviously not one of my strong points ;) I'll +1 your answer instead.
WoLpH
+2  A: 

If you are on a Mac or BSD or something else without the --date option, you can use:

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

Update: or perhaps...

date -r $((`date +%s` - 86400)) '+%a %d/%m/%Y'
DigitalRoss
That would be less awkward using `$()` instead of ````. ksh has `$()`?
bstpierre
+1 just for not assuming that every UNIX question is on Linux. Some of us have to work with other styles as well.
paxdiablo
@paxdiablo: agreed, but if no specific info is given than I personally assume that the GNU toolkit is an option ;) The differences between `HP-UX`, `AIX`, `Solaris` and `*BSD` are simply to great to guess the flavour.
WoLpH
Could this fail in weird corner-cases? Like when there is a leap-second?
Alok
@Alok: POSIX/Unix doesn't track leap seconds (all days are 86400 seconds), but there is a corner case with DST (see my comment on [paxdiablo's answer](http://stackoverflow.com/questions/3517982/in-a-unix-shell-how-to-get-yesterdays-date-into-a-variable/3518086#3518086)
Gilles
@DigitalRoss: Unfortunately `date +%s` is not POSIX either, though it's more widely available that `--date yesterday`.
Gilles
+4  A: 
dt=$(date --date yesterday "+%a %d/%m/%Y")
echo $dt
polemon
+1 for answering the question precisely.Caveat is that the -yesterday flag may not be supported on posters version of unix
James Anderson
+3  A: 

If you have Perl available (and your date doesn't have nice features like yesterday), you can use:

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
paxdiablo
Perfect! thanks a lot
Chris
@Chris: note that this gives you the date 24 hours ago, which is subtly different from yesterday's date. If your locale has daylight savings time, this will give the wrong date after 23:00 on the first day of winter time.
Gilles
@Gilles, that's not a bad point since I'm using locattime. If you're concerned about it, you can check if the hour is greater than 6pm, just subtract 6 hours. That should hopefully cover it.
paxdiablo
Good point gilles. I miss my C# <sob>: DateTime.Now.AddDays(-1)
Chris
A: 

Thanks for the help everyone, but since i'm on HP-UX (after all: the more you pay, the less features you get...) i've had to resort to perl:

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

On Linux, you can use

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

If your HP-UX installation has Tcl installed, you might find it's date arithmetic very readable (unfortunately the Tcl shell does not have a nice "-e" option like perl):

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

This will handle all the daylight savings bother.

glenn jackman