0

I want date output in format like...

01/01/2020
02/01/2020
03/01/2020
04/01/2020
05/01/2020
06/01/2020
07/01/2020
08/01/2020
09/01/2020
10/01/2020
11/01/2020
12/01/2020
13/01/2020
14/01/2020
15/01/2020
16/01/2020
17/01/2020
18/01/2020
19/01/2020
20/01/2020
21/01/2020
22/01/2020
23/01/2020
24/01/2020
25/01/2020
26/01/2020
27/01/2020
28/01/2020
29/01/2020
30/01/2020

currently I am using ...

cal 01 2020 | grep -v "[A-Z][a-z]"| tr ' ' '\n' | sort -n | awk '$1~/[0-9]/ { printf "%02s/%02s/%4s\n",$1,"01","2020"}'

I want format as above be for 01/01/2017 to 31/12/2019.How can I do this

1
#!/bin/bash

timestamp=$( date -d '2017-01-01 12:00' +%s )

while [ "$thedate" != '31/12/2019' ]; do
        printf -v thedate '%(%d/%m/%Y)T' "$timestamp"
        timestamp=$(( timestamp + 86400 ))

        printf '%s\n' "$thedate"
done

The above script first uses GNU date to get the UNIX timestamp for noon on the start date (it will be 1483268400). It then iterates until the end date has been found and outputted. In each iteration, we increment timestamp with 86400 seconds (24 hours).

The date strings are produced with the built-in printf utility in bash, which is able to format a datetime string from a UNIX timestamp with its %(...)T format (this requires bash release 4.3 or later). It also prints directly to the variable thedate with -v.

On some systems without GNU date, you would be able to get the start date's timestamp with the native date utility using another format of the command line arguments. On OpenBSD, for example, it's done with

date -j +%s 201701011200

See man date on your particular Unix.

Some extended implementations of awk could also be use:

awk 'BEGIN { print mktime("2017 01 01 12 00 00") }'

But if you have such an awk (GNU awk or mawk), then you might as well do the whole thing in awk:

awk '
BEGIN {
        timestamp = mktime("2017 01 01 12 00 00")

        while (thedate != "31/12/2019") {
                thedate = strftime("%d/%m/%Y", timestamp)
                timestamp += 86400

                print thedate
        }
}'
|improve this answer|||||
  • Its giving error invalid format character line3 i am using rhel 5.9 – Kalpesh Bhoj Feb 7 at 7:48
  • @KalpeshBhoj Line 3? I wonder what statement that would be? If it's the printf, then you may have a slightly too old bash. You could also try the awk code that I just added. – Kusalananda Feb 7 at 7:51
  • awk works beautifuly.Thanks – Kalpesh Bhoj Feb 7 at 7:56
  • @KalpeshBhoj I looked up RedHat 5.9, and it appears that it shipped with a fairly old release of bash, which is why the shell code doesn't quite work for you. Also note that that release of RedHat is quite old and that you may want to upgrade at some point soon. – Kusalananda Feb 7 at 8:00
  • FWIW using a %F date format for the date generation and calculations (or testing the timestamp in the loop instead of thedate) and then just shuffling the order of the fields for printing would let you do thedate < "2019-12-31" and so the code would then not go into an infinite loop if someone provided an invalid end date or a date that was before the start date. – Ed Morton Feb 8 at 13:52
-2

You would need to add a nested for-loop with first iteration for the year and the next - month. for each month, you would do what you've already done, printing the month and year in the end of the awk.

|improve this answer|||||
  • 1
    Can you expain for loop ? – Kalpesh Bhoj Feb 7 at 7:21
  • If you want to cycle through a set of things. you can type it in shell: for i in {1..12} >do > echo $i >done This will print out the numbers from 1 to 12 All on one line: `for i in {1..12}; do echo $i; done The other solution is better, as it requires less typing. – Karov Feb 7 at 8:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.