Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'd like to make validation about time stamp of one of my log file. But it seems I have problem on my expression in case statement.

TIME value might be something like 11:49 or 2011. And I just want to check whether it is HH:MM format or not. Code is in below.
It is always saying year format althought file is in HH:MM format

TIME=`ls -lrth  /var/log/*.log |  grep -i upg | tail -1 | awk '{print $8}'`
echo "$TIME"
if [[ $TIME != "" ]]
  case TIME in
     "[0-23]+ :[0-59]")
  *) echo "Year format";;

echo "$validation

Update : I tried "[0-2][0-9]:[0-5][0-9]") but validation still return fail.

share|improve this question
mibzer. You put what you call a comment into an anser. You, as the questioner, should confine your comments to comment entries (not Answers). When you have new significant data which doesn't easily fit into a comment, just update your answer, and refer to that in you comment.... Re your problem: you are mixing 2 types of expressios: glob style expressions and regular expressions. The bash case statement uses regular expressions. You need to remove the "quotes" ... bash regular expressions need to be exposed; not protected by quotes... If you need spaces, just escape them with \ – Peter.O Jul 18 '12 at 13:02
@Peter.O Thank you Peter and sorry for confusion. – mibzer Jul 18 '12 at 14:00
There is a mistake in my previous comment: case uses a glob style expression. – Peter.O Jul 18 '12 at 15:07
I think you're on the right track using case expressions, but you don't understand the rules of the character class expressions, i.e. [0-23] means "only 1 char matching" either 1). the range 0-2 (i.e. 0,1,2) OR 2) the single number number 3, NOT 0 hrs to 23 hrs as I'm guessing you mean. ---- Inside sq-brackets, each char stands for itself as a match for one char, excepting when the range notation is use as 0-2. You can use reg expers in this case to get mostly what you want, ie case TIME in [0-2][0-9]\ :[0-5][0-9]). Read it one sq-brkt at a time, what ever inside is a single match. GL. – shellter Jul 19 '12 at 4:38
up vote 2 down vote accepted

The problem is that you can't check TIME with [0-23]+ :[0-59] expression.

There are several ways to do it:

  • To split your variable and check each part separately:
TIME="06:25" ; 
[[ $TIME != "" ]] && \
[ ${TIME%:*} -le 23 -a ${TIME%:*} -ge 0 -a \
        ${TIME#*:} -le 59 -a ${TIME#*:} -ge 0 ] && echo ok
  • To check it with common regex, but it will accept some cases of wrong time (like 28:59):
share|improve this answer
please see my below comment. – mibzer Jul 18 '12 at 12:45
your first advice worked thx, but I have one more question what is TIME%:* and TIME#* mean ? . I haven't used them before – mibzer Jul 18 '12 at 12:56
TIME%:* delete all symbols after first : from the beginning of the variable, TIME#* delete all symbols after first : from the end of the variable. You can find more detailed explanation here: tldp.org/LDP/abs/html/parameter-substitution.html – rush Jul 18 '12 at 13:08
You can be exact with expression matching: 1. "normal" regular expression, using =~: [[ $time =~ ^([01][0-9]|2[0-4]):[0-5][0-9]$ ]] 2. glob expression, using ==: [[ $time == @([01][0-9]|2[0-4]):[0-5][0-9] ]] – Peter.O Jul 18 '12 at 15:14

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.