다음 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" 코드를 실행합니다. 앞에 0을 붙인 것이 문제일 수 있다고 생각하나요? [[ .. ]]를 사용해도 같은 일이 일어납니다.
다음과 같이 수정하면 작동합니다.
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
앞에 0이 있다는 것이 아닙니다. 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이면 이고 , 그렇지 않으면 (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
.