산술 확장(선행 0)으로 테스트

산술 확장(선행 0)으로 테스트

다음 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크지 않으므로 절이 실행됩니다. 테스트를 간단한 것으로 변경할 수 있습니다.2else

[ $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이 아닐 경우 현재 연도로 설정되고, 그렇지 않으면 이전 연도로 설정됩니다 .1m0p_m_ym


그건 그렇고, 당신은 이렇게 말했습니다.

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.

관련 정보