Results 1 to 5 of 5
  1. #1
    Join Date
    Sep 2014
    Posts
    2

    Unanswered: incrementing dates in ksh

    Hi,

    I am relatively new to scripting. I have a file called start_date that has a date in this format (year|month): 1997|08 and a file called end_date that has a date in this format (year|month) 1998|05. I need to increment the dates in between and put them all in a file so that it looks like this...

    1997|08
    1997|09
    1997|10
    1997|11
    1997|12
    1998|01
    1998|02
    1998|03
    1998|04
    1998|05

    This needs to work for any dates that are input into the start_date and end_date files.

    Here's what I have so far, but it's not working. I feel like maybe I need an until loop in there somewhere...

    start_date=`cat start_date`
    end_date=`cat end_date`

    start_month=${start_date#?????}
    start_year=${start_date%???}
    end_month=${end_date#?????}
    end_year=${end_date%???}

    if [[ $start_month == $end_month && $start_year == $end_year ]]
    then
    print "$start_year|$start_month" > $dates
    elif [ $start_month = 12 ]
    then
    start_month=01
    yr=`expr $start_year + 1`
    print "$yr|$start_month" >> $dates
    else
    start_month=`expr $start_month + 1`
    yr=$start_year
    print "$yr|$start_month" >> $dates
    fi

  2. #2
    Join Date
    Sep 2009
    Location
    Ontario
    Posts
    1,057
    Provided Answers: 1
    Code:
    #!/bin/bash                   
    IFS="|"                       
    read startyear startmo <start_date        
    read endyr endmo <end_date         
    work=$startyear$startmo               
    end=$endyr$endmo              
    while [ $work -lt $end ]      
    do                            
        echo ${work:0:4}\|${work:4:2} 
        work=`expr $work + 1`         
        mo=${work:4:2}                
        if [ $mo -eq 13 ]           
            then                  
            work=`expr $work + 88`
        fi                            
    done                          
    echo $endyr\|$endmo
    As you can see, I have approached the problem slightly differently than you.
    First, IFS (internal field separator) is set to |, rather than the default white space.
    Read(ing) the input, saves calling an external process (cat).
    By creating a single field for the year/month, the year end comparison and update is simplified.
    Last edited by kitaman; 09-27-14 at 15:18. Reason: spelling

  3. #3
    Join Date
    May 2014
    Posts
    6
    hi,

    `expr' is a useless external program; any POSIX compatible shell can use arithmetic evaluation: `$(( ... ))'

  4. #4
    Join Date
    Sep 2014
    Posts
    2

    Thanks for the replies

    Thank you so very much for the replies. I tried something a little different which seems to work fine. I added the day (01) to the date and then used date -d to calculate the date. Please tell me if this is inefficient or is not a good way to go:

    start_date=`cat start_date`
    end_date=`cat end_date`

    start_month=${start_date#?????}
    start_year=${start_date%???}
    end_month=${end_date#?????}
    end_year=${end_date%???}

    new_start_date=$start_year"-"$start_month"-01"
    new_end_date=$end_year"-"$end_month"-01"

    if [[ $start_month == $end_month && $start_year == $end_year ]]
    then
    print "$start_year|$start_month" > $dates
    else
    while [ $new_start_date != $new_end_date ]
    do
    new_start_date=$(date -d "$new_start_date + 1 month" "+%Y-%m-%d")
    print "new_start_date is $new_start_date"
    new_start_month1=${new_start_date#?????}
    new_start_month=${new_start_month1%???}
    new_start_year1=${new_start_date%???}
    new_start_year=${new_start_year1%???}
    print "$new_start_year|$new_start_month" >> $dates
    done
    fi

  5. #5
    Join Date
    Sep 2009
    Location
    Ontario
    Posts
    1,057
    Provided Answers: 1
    Amanda,
    When you add code to a post, use code tags (either highlight the text that is code, and use the # tool in the tool bar, or type "code" without the quotation marks, but with square brackets, at the beginning of the code, and "/code" at the end.

    Efficiency is a moving target.
    Does your code work? Is it easy to read? Could someone else modify it without coming back to ask questions?
    Are you going to run this code once per year or a million times a day?

    Do you think that you could simplify your code if you changed the date mask in the date command to "+%Y|%m" ?
    was
    Code:
    new_start_date=$(date -d "$new_start_date + 1 month" "+%Y-%m-%d")
    new
    Code:
    new_start_date=$(date -d "$new_start_date + 1 month" "+%Y|%m")
    How would doing this affect the rest of the code?

    You can check the computer efficiency of a script by running it in the time command. Just put the word "time" in front of the command you want to test so:

    Code:
    bash-3.2# time df -v                                                   
    time df -v                                                             
    Mount Dir  Filesystem              blocks      used      free   %used  
    /          /dev/root            130867184   8297392 122569792     7%   
    /stand     /dev/boot                52344     12418     39926    24%   
    /u         /dev/u               130867184  46185232  84681952    36%   
    /home      /dev/home             47258760  17041096  30217664    37%   
                                                                           
    real    0m0.025s                                                       
    user    0m0.000s                                                       
    sys     0m0.000s                                                       
    bash-3.2#

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •