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")