43

I have this:

date +"%H hours and %M minutes" 

I use festival to say it up.. but it says like: "zero nine hours".. I want it to say "nine hours"!

but date always give me 09... so I wonder if bash can easly make that become just 9?

in the complex script I tried like

printf %d 09 

but it fails.. not octal :(

any idea?

3
  • OP, your accepted answer is great - for your specific case, but it doesn't match the question title. Commented Sep 13, 2016 at 8:47
  • @ilkkachu the old title was key in me finding this question, looking for forcing decimal interpretation of octal-format numbers. Commented Jun 4, 2018 at 7:55
  • @muru, yeah, I thought if I could stick the note about octal there, but didn't come up with a nice phrasing. You could change it of course, at least you know what you searched for? The answers and question still mainly seem to be about removing the leading zero. Commented Jun 4, 2018 at 8:03

4 Answers 4

59
  • In your case, you can simply disable zero padding by append - after % in the format string of date: %-H

    By default, date pads numeric fields with zeroes. The following optional flags may follow '%':

    • - (hyphen) do not pad the field
    • _ (underscore) pad with spaces
    • 0 (zero) pad with zeros
    • ^ use upper case if possible
    • # use opposite case if possible

    See date manual

  • If you want to interpret number in different base, in bash

    • Constants with a leading 0 are interpreted as octal numbers.
    • A leading 0x or 0X denotes hexadecimal.
    • Otherwise, numbers take the form [base#]n, where base is a decimal number between 2 and 64 representing the arithmetic base, and n is a number in that base

    So, to interpret a number as decimal, use 10#n form, eg. 10#09

    echo $((10#09*2)) 18 

    See Arithmetic Evaluation section of bash manual.

3
  • 2
    thx, very detailed! btw, echo $((011)) $((10#011)) is another good example that outputs 9 11 Commented Apr 29, 2013 at 21:10
  • 1
    This does not work for negative numbers: lat=048 ; latd=${lat#0} ; echo $((latd-1)) works, but lat=-048 ; latd=${lat#0} ; echo $((latd-1)) doesn't. Commented Feb 12, 2016 at 0:17
  • plus=$((10#01)) Commented Mar 24, 2017 at 23:21
2

If you're trying to do comparisons in decimal with date values, I've found this method to be very effective:

let mymin=$(date '+1%M') ; let mymin=$mymin%100 

That always yields a decimal value. So I can do this:

if [[ $mymin -le 1 ]]; then # only 0 and 1 are true. 

There's no problem with 08 or 09 this way. Using %10 instead of %100 gives you ten-minute ranges from 0 through 9. I also find the following gives decimal values, without leading zeros:

echo "$((10#$(date +%M)))" 
2

Portably, you can easily remove a leading 0 from a variable. This leaves the variable unchanged if there is no leading 0.

eval $(date +"h=%H m=%M") h=${h#0} m=${m#0} say "$h hours and $m minutes" 

In bash, ksh or zsh, you can use ksh's additional glob patterns to remove any number of leading 0s. In bash, run shopt -s extglob first. In zsh, run setopt kshglob first.

eval $(date +"h=%H m=%M") h=${h#+(0)} m=${m#+(0)} say "$h hours and $m minutes" 
1

In general in bash:

test ${#number} -eq 2 && number=${number#0} 

resulting in

date +"%H %M" | { read hours minutes hours=${hours#0} minutes=${minutes#0} echo "${hours} hours and ${minutes} minutes"; } 

Or, different:

date +"%H hours and %M minutes" | sed -n -e 's/0\([0-9]\)/\1/g' -e p 

I am surprised that date does not have appropriate format options.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.