次のksh88コードは、月[m]と年[y]の値を取り、先月の年[p_m]と先月[p_m_y]を計算します。
m は元の date コマンドから出てくるので、現在の月が 10 より小さい場合は前に 0 が付きます。
m=02
y=2017
if [ $((m-1)) -gt 1 ]
then
p_m=$((m-1))
p_m_y=$((y))
else
p_m=12
p_m_y=$((y-1))
fi
この例では、p_mは12に設定され、p_m_yは2016なので、ifステートメントは失敗したように見え、mが1より大きい場合でも常に "else"コードを実行します。前にゼロを付けるのが問題かもしれないと思いますか? [[..]]を使っても同じことが起こります。
次のように変更すると機能します。
if [[ $((m-1)) != 01 ]]
おそらくこれは文字列比較です。算術比較は機能しません。大きな問題ではなく、まだ解決できます。
ただし、正しい算術を使用してこれを操作する方法が必要です。 Base10拡張を強制しようとすると、何の効果もありません。
if [[ $((10#$m-1)) -gt 1 ]]
答え1
月が1 =>先月=> 12で年が減少したときに呼び出されるdc
電卓を使用します。macro
a
それ以外の場合は年を減らします。
m=01
y=2011
set X `echo "[sa 1- 12]sa $y $m d1- r1- r0 =af" | dc`; shift
p_m=$1 p_m_y=$2
echo "Current month:$m Current year: $y"
echo " Prev month:$p_m Prev month year: $p_m_y"
答え2
あなたが示した特定の例の問題は、m
前にゼロがあるということではありません。 8進数で処理されても02
まだ0です2
。使用中のテストは次のとおりです。
[ $((m-1)) -gt 1 ]
しかし、m-1 > 1
はと同じですm > 2
。より2
大きくないので、句が実行されます。テストを簡単なものに変更できます。2
else
[ $m -gt 1 ]
しかし、シェルの算術関数を直接使用する方がはるかに簡単です。
m=02
y=2017
p_m=$(( (m+10)%12 + 1 ))
p_m_y=$(( y - (m==1) ))
この最後のポイントは、おそらくいくつかの説明が必要です。
ではp_m
モジュラー操作を使用します。 (m + 10)%12
「2ヶ月前(または10ヶ月後)」と同じです。ただし、12月は0として表示されます。次に、「先月、範囲1-12」を実装するために1つを追加します。
最後の行はより簡単です。値が1の場合、それ以外の場合(m==1)
。 1以外の場合は現在の年に設定され、それ以外の場合は前の年に設定されます。1
m
0
p_m_y
m
ところで、あなたはこう言いました。
m は元の date コマンドから出てくるので、現在の月が 10 より小さい場合は前に 0 が付きます。
必ずしもそうではありません。私のシステムでは:
$ date
2017年 5月 9日 火曜日 13:58:53 EDT
$ LC_ALL=en_US.UTF-8 date
Tue May 9 13:58:53 EDT 2017
$ date '+%Y %m %d' | sed 's/ 0*/ /g'
2017 5 9
したがって、数字が8進数として解釈されるのが心配な場合は、最後の数字を試してみることをお勧めします。
答え3
これはうまくいきます。次の環境でテストしましたksh
。
if [[ $((m-1)) -eq 1 ]]; then echo "Equal"; fi
にも適用されます-gt
。