2

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.

4
  • 2
    dseq is a program, not a built-in command of zsh. If you are on Ubuntu, try to install dateutils: sudo apt-get install -y dateutils. Then dateseq 5 works. It was apparently recently renamed: ubuntu 16 was called dseq: manpages.ubuntu.com/manpages/xenial/en/man1/… now dateseq: manpages.ubuntu.com/manpages/bionic/en/man1/… Commented May 7, 2022 at 18:01
  • @masterxilo I am not Ubuntu. I am on MacOS Commented May 7, 2022 at 18:03
  • 2
    @jgg then brew install dateutils should do it. Commented May 7, 2022 at 18:03
  • @Maroun this helped. And then I typed dateseq 2022-05-01 Commented May 7, 2022 at 18:18

2 Answers 2

4

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 
Sign up to request clarification or add additional context in comments.

4 Comments

I get the following error: date: illegal option -- d usage: date [-jnRu] [-r seconds|file] [-v[+|-]val[ymwdHMS]] [-I[date | hours | minutes | seconds]] [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
@jgg Try brew install coreutils and then use gdate. Check this answer.
The -d option is specific to GNU date. If you are on MacOS, the system date command is somewhat clunkier, so perhaps a more elegant solution would be e.g. a simple Perl script.
on BSD it would be date -v "+${i}d" +%Y-%m-%d
0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.