web-dev-qa-db-ja.com

「日付」の出力から先行ゼロを削除する方法、またはそのような10進数の8進数解釈を回避するにはどうすればよいですか?

私はこれを持っています:

date +"%H hours and %M minutes"

フェスティバルを使って言いますが、「ゼロナインアワー」と言います。「ナインアワー」と言いたいです。

しかし、日付は常に私に09を与えます...それで、bashはそれを簡単に9にすることができるのでしょうか?

私が試した複雑なスクリプトで

printf %d 09

しかし、失敗します。8進数ではありません:(

何か案が?

40
Aquarius Power
  • あなたの場合、日付のフォーマット文字列で-の後に%を追加することにより、ゼロパディングを無効にすることができます:%-H

    デフォルトでは、日付は数値フィールドにゼロを埋め込みます。以下のオプションのフラグが '%'の後に続く場合があります。

    • -(ハイフン)フィールドを埋め込みません
    • _(アンダースコア)スペース付きパッド
    • 0(ゼロ)ゼロを埋め込む
    • ^可能であれば大文字を使用
    • #可能な場合は逆のケースを使用

    参照 日付マニュアル

  • 数値を別のベースで解釈したい場合は、bashで

    • 先頭が0の定数は、8進数として解釈されます。
    • 先頭の0xまたは0Xは16進数を示します。
    • それ以外の場合、数値は[base#] nの形式をとります。ここで、baseは算術基底を表す2から64までの10進数で、nはその基底の数値です

    したがって、数値を10進数として解釈するには、10#n形式を使用します。 10#09

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

    Bashマニュアルの 算術評価 セクションを参照してください。

51
LiuYan 刘研

10進数で日付値と比較しようとしている場合、この方法が非常に効果的であることがわかりました。

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

これにより、常に10進値が生成されます。だから私はこれを行うことができます:

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

この方法で08または09に問題はありません。 %100の代わりに%10を使用すると、0から9までの10分の範囲が得られます。また、次の例では、先行ゼロなしの10進数値が示されています。

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

移植性に優れ、変数から先頭の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"

一般的に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

日付に適切なフォーマットオプションがないことに驚いています。

1
Hauke Laging