Home > Software design >  How can I get a sequence of dates in bash?
How can I get a sequence of dates in bash?

Time:05-08

In Z shell there is a command called dseq which produces consecutive dates. For example:

$ dseq 5
2022-05-08
2022-05-09
2022-05-10
2022-05-11
2022-05-12

Is there a similar command in bash? I tried the following which gets me close to the desired output.

$ seq -f "2022-05-%g" 5
2022-05-1
2022-05-2
2022-05-3
2022-05-4
2022-05-5

Two issues:

  1. how can I pad the days with 0 so the output contains two-digit days?
  2. how can I start the sequence from today versus the first of the month?

Desired output should match output of $ dseq 5 above.

CodePudding user response:

You can have something like:

$ for i in {1..5}; do date -d "20220507 $i day"  %Y-%m-%d; done
2022-05-08
2022-05-09
2022-05-10
2022-05-11
2022-05-12

CodePudding user response:

If you are on MacOS and don't want to install GNU date (which is what provides the nonstandard -d option which you'll find in most answers to related questions) you will need to perform relative date calculations yourself. Perhaps like this:

base=$(date  "%s")
for((i=0; i<5;   i)); do
    date -r $((i * 24 * 60 * 60   base))  %Y-%m-%d
done

This avoids any complex date manipulations; if you need them, they are somewhat unobvious, and less versatile than the GNU date extensions - see, for example, How to convert date string to epoch timestamp with the OS X BSD `date` command?

For what it's worth, GNU date (and generally GNU userspace utilities) are the default on most Linux platforms.

With GNU date you could do date -d @timestamp format where MacOS/BSD uses date -r timestamp format.

If you need a portable solution, POSIX is not much help here, but a reasonably de facto portable solution is to use e.g. Perl. For inspiration, perhaps review What is a good way to determine dates in a date range?

perl -le 'use POSIX qw(strftime);
    $t = time;
    for $_ (1..5) {
        print strftime("%Y-%m-%d", localtime($t));
        $t  = 24 * 60 * 60 }'

Demo (on Linux): https://ideone.com/WkAoib

In case it's not obvious, both these solutions get the current time's epoch (seconds since Jan 1, 1970) and then add increments of 24 hours * 60 minutes * 60 seconds to jump ahead one day at a time.

  •  Tags:  
  • bash
  • Related