如何从“日期”的输出中删除前导零或避免对此类十进制数字进行八进制解释?


37

我有这个:

date +"%H hours and %M minutes"

我用节日说出来..但它说:“零九小时” ..我想说“九小时”!

但是约会总是给我09 ...所以我想知道bash是否可以轻松使它变成9?

在我尝试过的复杂脚本中

printf %d 09

但失败..不是八进制:(

任何想法?


OP,您接受的答案很好-针对您的具体情况,但与问题标题不匹配。
einpoklum-恢复莫妮卡

@ilkkachu,旧标题是我找到此问题的关键,它要求对八进制数字进行十进制解释。
大师

@muru,是的,我想我可以在此处保留有关八进制的音符,但没有提出好的措辞。您当然可以更改它,至少您知道搜索的内容吗?答案和问题似乎仍然主要是关于删除前导零。
ilkkachu

Answers:


49
  • 在您的情况下,您可以通过在date格式字符串中追加-after 来简单地禁用零填充%%-H

    默认情况下,日期填充数字字段为零。以下可选标志可以在“%”之后:

    • - (连字符)不要填充字段
    • _ (下划线)填充空格
    • 0 (零)填充零
    • ^ 尽可能使用大写
    • # 如果可能,使用相反的情况

    日期手册

  • 如果要以不同的底数解释数字,请使用bash

    • 前导0的常量被解释为八进制数。
    • 前导0x或0X表示十六进制。
    • 否则,数字采用[base#] n的形式,其中base是2到64之间的十进制数,代表算术底数,n是该底数中的数字

    因此,要将数字解释为十进制,请使用10#n格式。10#09

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

    请参见bash手册的“ 算术评估”部分。


2
thx,很详细!顺便说一句,这echo $((011)) $((10#011))是另一个输出的好例子9 11
Aquarius Power

1
这不适用于负数:lat=048 ; latd=${lat#0} ; echo $((latd-1))有效,但lat=-048 ; latd=${lat#0} ; echo $((latd-1))无效。
路易斯·弗洛里特

plus=$((10#01))
Beco博士

2

如果您尝试用十进制值与日期值进行比较,我发现此方法非常有效:

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

总是产生一个十进制值。所以我可以这样做:

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

这样08或09没问题。使用%10而不是%100可以为您提供从0到9的十分钟范围。

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

2

可移植地,您可以轻松地0从变量中删除前导。如果没有前导,这将使变量保持不变0

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

在bash,ksh或zsh中,可以使用ksh的其他glob模式删除任意数量的前导0s。在bash中,shopt -s extglob先运行。在zsh中,setopt kshglob首先运行。

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

1

通常在bash中:

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

导致

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

或者,不同:

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

我很惊讶日期没有适当的格式选项。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.