Home > Software design >  Shell script - is there a faster way to write date/time per second between start and end time?
Shell script - is there a faster way to write date/time per second between start and end time?

Time:01-13

I have this script (which works fine) that will write all the date/time per second, from a start date/time till an end date/time to a file

while read line; do
    FIRST_TIMESTAMP="20230109-05:00:01" #this is normally a variable that changes with each $line

    LAST_TIMESTAMP="20230112-07:00:00" #this is normally a variable that changes with each $line

    date=$FIRST_TIMESTAMP
    while [[ $date < $LAST_TIMESTAMP || $date == $LAST_TIMESTAMP ]]; do
        date2=$(echo $date |sed 's/ /-/g' |sed "s/^/'/g" |sed "s/$/', /g")
        echo "$date2" >> "OUTPUTFOLDER/output_LABELS_$line"
        date=$(date -d "$date  1 sec"  "%Y%m%d %H:%M:%S")
    done
done < external_file

However this sometimes needs to run 10 times, and the start date/time and end date/time sometimes lies days apart. Which makes the script take a long time to write all that data.

Now I am wondering if there is a faster way to do this.

CodePudding user response:

Using epoch time ( %s and @) with GNU date and GNU seq to produce datetimes in ISO 8601 date format:

begin=$(date -ud '2023-01-12T00:00:00'  %s)
  end=$(date -ud '2023-01-12T00:00:12'  %s)
seq -f "@%.0f" "$begin" 1 "$end" |
date -uf - -Isec
2023-01-12T00:00:00 00:00
2023-01-12T00:00:01 00:00
2023-01-12T00:00:02 00:00
2023-01-12T00:00:03 00:00
2023-01-12T00:00:04 00:00
2023-01-12T00:00:05 00:00
2023-01-12T00:00:06 00:00
2023-01-12T00:00:07 00:00
2023-01-12T00:00:08 00:00
2023-01-12T00:00:09 00:00
2023-01-12T00:00:10 00:00
2023-01-12T00:00:11 00:00
2023-01-12T00:00:12 00:00

CodePudding user response:

Avoid using a separate date call for each date. In the next example I added a safety parameter maxloop, avoiding loosing resources when the dates are wrong.

#!/bin/bash
awkdates() {
  maxloop=1000000

  awk \
    -v startdate="${first_timestamp:0:4} ${first_timestamp:4:2} ${first_timestamp:6:2} ${first_timestamp:9:2} ${first_timestamp:12:2} ${first_timestamp:15:2}" \
    -v enddate="${last_timestamp:0:4} ${last_timestamp:4:2} ${last_timestamp:6:2} ${last_timestamp:9:2} ${last_timestamp:12:2} ${last_timestamp:15:2}" \
    -v maxloop="${maxloop}" \
    'BEGIN {
      T1=mktime(startdate);
      T2=mktime(enddate);
      linenr=1;
      while (T1 <= T2) {
         printf("%s\n", strftime("%Y%m%d %H:%M:%S",T1));
         T1 =1;
         if (linenr   > maxloop) break;
      }
   }'
}

mkdir -p OUTPUTFOLDER
while IFS= read -r line; do
  first_timestamp="20230109-05:00:01" #this is normally a variable that changes with each $line
  last_timestamp="20230112-07:00:00" #this is normally a variable that changes with each $line
  awkdates >> "OUTPUTFOLDER/output_LABELS_$line"
done < <(printf "%s\n" "line1" "line2")
  • Related