Date Combinations

Hi,

A friend showed my how to create a file that contains:

$0$0$0$0
$0$0$0$1
....
$9$9$9$9

with the line
(Toggle Plain Text)

printf '%s\n' $\{0..9}$\{0..9}$\{0..9}$\{0..9}


I now now needing to create a similar file that is all the combinations of:

$d$d$m$m

Where dd = days of month and months of year, ie dd = 01-31 and mm = 01-12
ie

$0$1$0$1 # first jan
$0$1$0$2 # second jan
..
$3$1$1$2 # 31st dec

I also want to create mmyy file (where yy = 00 to 99)

$0$1$0$1 # short date format for Jan 2000 or Jan 1900
...
$1$2$9$9 # short date format for Dec 1999

I assume I need a counter, but my bash isnt good enough to work in a counter.

Could someone please assist?

Many thanks

-Al

Comments

  • As this is the sed and awk forum, here are the loops you need in awk:

    day and month:
    bigalnz $] cat day_month.awk
    #!/bin/gawk -f
    
    BEGIN{
    
        #
        days_per_month[1]=31;
        days_per_month[2]=28;
        days_per_month[3]=31;
        days_per_month[4]=30;
        days_per_month[5]=31;
        days_per_month[6]=30;
        days_per_month[7]=31;
        days_per_month[8]=31;
        days_per_month[9]=30;
        days_per_month[10]=31;
        days_per_month[11]=30;
        days_per_month[12]=31;
    
        for(month=1; month<=12; month=month+1){
            n_days=days_per_month[month];
            for(day=1; day<=n_days; day=day+1){
                d_tens=day/10;
                d_units=day%10;
                m_tens=month/10;
                m_units=month%10;
                printf("$%d$%d$%d$%d\n", d_tens, d_units, m_tens, m_units);
    
            }
        }
    }[bigalnz $] ./day_month.awk
    $0$1$0$1                              
    $0$2$0$1                              
    $0$3$0$1                              
    $0$4$0$1                              
    $0$5$0$1                              
    $0$6$0$1                              
    $0$7$0$1                              
    $0$8$0$1           
    
    clipped 
    
    $2$6$1$2
    $2$7$1$2
    $2$8$1$2
    $2$9$1$2
    $3$0$1$2
    $3$1$1$2
    [bigalnz $]
    
    
    

    month and year:

    
    [bigalnz $] cat ./month_year.awk
    #!/bin/gawk -f
    
    BEGIN{
    
        for(year=00; year<=99; year=year+1){
            for(month=1; month<=12; month=month+1){
                m_tens=month/10;
                m_units=month%10;
                y_tens=year/10
                y_units=year%10
    
                printf("$%d$%d$%d$%d\n", m_tens, m_units, y_tens,y_units);
                #print y_tens " " y_units ;
    
            }
        }
    }[ bigalnz $] ./month_year.awk 
    $0$1$0$0
    $0$2$0$0
    $0$3$0$0
    $0$4$0$0
    $0$5$0$0
    $0$6$0$0
    
    clipped 
    
    $0$3$9$9
    $0$4$9$9
    $0$5$9$9
    $0$6$9$9
    $0$7$9$9
    $0$8$9$9
    $0$9$9$9
    $1$0$9$9
    $1$1$9$9
    $1$2$9$9
    [bigalnz $]
    
    
    


    If this is no good for you, you can loop in bash with the following construction:

    
    for (( i=0 ; i < 100 ; i++ )) ; do 
      echo $i 
    done ; 
    
    


    Have another go and if you're still stuck, post back.

    hth.
  • The solution given by sharted is clear and readable.

    I offer one here which is relatively concise but admittedly less readable.
    The significance of my solution is that it takes a different approach.
    Rather than use a table of month lengths, it makes a "calendar" in which
    every month has 31 days, and then "knocks out" the 7 unwanted days.
    # Build a calendar such that each month has 31 days,
    #   then "knock out" the superflous dates.
    awk 'BEGIN{for (j=1;j<=31;j++) d=d "$"int(j/10)"$"j%10" "; split(d,day," ");
               for (j=1;j<=12;j++) {w=d; gsub(/ /,day[j]"\n",w); c=c w};
               gsub(/.2.9.0.2\n|.3.0.0.2\n|.3.1.0.2\n|.3.1.0.4\n|\
                     .3.1.0.6\n|.3.1.0.9\n|.3.1.1.1\n/,"",c);
               print c}' >$OutFile
    

    Daniel B. Martin
  • As a matter of personal coding style I try to avoid explicit loops.
    Here is an even more concise (and less readable) solution.

    # Build a calendar such that each month has 31 days,
    # then "knock out" the 7 superfluous dates.
    # This method uses no explicit loops.
    seq 0 371  \
    |awk -F "" '{sum[k=1+int($0/31)]++; $0=sprintf("%02d%02d",sum[k],k);
      if ($0!~/2902|3002|3102|3104|3106|3109|3111/) print $1"$"$2"$"$3"$"$4}'  \
    >$OutFile
    

    Daniel B. Martin
  • Thanks guys. Both work very well.
Sign In or Register to comment.