The original https://lists.debian.org/debian-user/2025/07/msg00407.html specified HH:MM:SS format for input, nothing more, nothing less. And sure, we should validate input and, e.g. throw error if input isn't valid. But if we want to accept additional, well, that should also be in the earlier specification. Also, the earlier context, YouTube video durations, also not likely we'll be dealing with > 99H 59M 59S video durations. And quick search seems to suggest YouTube currently has a max. video duration of 12 hours.
And sed and awk are POSIX, so using those is POSIX, so long as we restrict ourselves to specified POSIX functionality. And yes, could do it entirely within POSIX shell, no external commands/programs at all, though that may be fair bit more code. Others have suggested, e.g. python. Certainly python or perl or the like could be used, code would be more concise, but system overhead would generally be significantly larger. sed and awk are comparatively lightweight, and quite POSIX, though not as system efficient as doing it only within the shell itself, at least presuming we're already in a POSIX (capable) shell context. I also left out input validation in the interests of brevity, but of course that's easy to add. A more complete POSIX compliant example: #!/bin/sh # Take our HH:MM:SS format 1st and only argument, # convert to seconds and write that to stdout. set -e LC_ALL=C export LC_ALL # [ test is not guaranteed to be built-in to POSIX shell, so we'll try # to stick to what must be internal only. # same applies to echo (plus its other (potential) issues) case "$# $1" in 1\ [0-9][0-9]:[0-9][0-9]:[0-9][0-9]) : ;; *) 1>&2 printf '%s\n' \ "${0##*/}: usage, requires single argument in format HH:MM:SS, aborting" exit 1 ;; esac h=${1%%:*} h=${h#0} hm=${1%:*} m=${hm#*:} unset hm m=${m#0} s=${1##*:} s=${s#0} printf '%s\n' $((3600 * h + 60 * m + s)) Of course in the original post, more full context wasn't mentioned. So, e.g., did they want a separate standalone program for this? Or were they wanting to do it in existing POSIX shell program, or perhaps even existing interactive POSIX shell session. In that case they may want something a simple as a copy-paste one-liner that they could then easily reuse from shell history for some convenient bit. (hhmmss=09:08:07; set -e; LC_ALL=C export LC_ALL; case "$hhmmss" in [0-9][0-9]:[0-9][0-9]:[0-9][0-9]) :;; *) exit 1;; esac; h=${hhmmss%%:*}; h=${h#0}; hm=${hhmmss%:*}; m=${hm#*:}; unset hm; m=${m#0}; s=${hhmmss##*:}; s=${s#0}; printf '%s\n' $((3600 * h + 60 * m + s))) Or maybe they'd want to add similar to an existing POSIX shell program, with bit of suitable reformatting, and replace the exit 1 with return 1 within a function, or some more suitable/complete error handling, and perhaps augment the set -e with some more general error trapping and handling via trap. On Sat, Jul 19, 2025 at 5:26 AM Greg Wooledge <g...@wooledge.org> wrote: > On Fri, Jul 18, 2025 at 21:08:09 -0700, Michael Paoli wrote: > > echo \ > > $(( > > $( > > d12='\([0-9]\{1,2\}\)' > > echo 09:10:11 | > > sed -e ' > > s/^/ / > > s/:/ /g > > s/ 0*\([0-9]\)/ \1/g > > '" s/^ $d12 $d12 $d12"'$/3600 * \1 + 60 * \2 + \3/ > > ' > > ) > > )) > > I don't like this one as much. It's better than the original one-liner > (both because it's actually correct -- I think! -- and because it's in > a format that's a little bit easier to read), but it still looks like > it was written by someone who is bound and determined to use sed for this, > no matter how difficult it may be. > > Also, the use of [0-9]\{1,2\} for the first segment means you're > hard-capping this to 99:59:59 and will never be able to handle 100:23:45. > That might be OK, or not. I don't know whether there are any restrictions > on the durations the OP is dealing with. I would've used \{1,\} to > remove the two-digit limit, if I had to do it this way.