3

I have a bash script that reads in lots of dates in epoch time, and determines the (local) hour of the day at which they occurred. Relevant snippet:

while read ts
do
  hour="$(date -d@$((${ts} / 1000)) +%H)"
  ((hourly_counts["${hour}"]+=1))
done < "${jqfile}"

It's rather slow, because it spawns a new subshell for each invocation of date. Is there a sensible way round this? It looks as though date doesn't support multiple queries.

All I can think of is to spawn a new shell, and pipe date commands to it and get the results back, so that they all execute in the same shell. But I'm not clear on how to do this, and it seems a little over-engineered.

chiastic-security
  • 20,430
  • 4
  • 39
  • 67

1 Answers1

4

Use printf:

printf -v hour '%(%H)T' "$(( ts / 1000 ))"

Type help printf to know more about the command.

Also check strftime(3). Behavior may depend on the value of TZ and LC_TIME.

konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • 1
    Wow, that is very cool, I didn't know printf could handle timestamps! – chiastic-security Jan 04 '22 at 11:45
  • I'm still interested to know if there's a solution to the more general problem, though (not specific to `date`, but just needing to run lots of commands without spawning a subshell for each). – chiastic-security Jan 04 '22 at 11:46
  • @chiastic-security For that, I think your original idea sounds pretty good. I've used that technique when I needed to speed up commands sent to an interpreter (`cleartool` in that case) and it helped a lot. You could perhaps set the prompt to `PS1='\n[$?] ~~~~delimiter~~~~\n'` to make it easy to parse when the output from the previous command is done (and what exit status it had. – Ted Lyngmo Jan 04 '22 at 13:32