나는 Bash에서 "역 부호" 기능을 더 잘 구현하는 데 관심이 있습니다. 나는 다음과 같은 일을 할 수 있다는 것을 알고 있습니다.
"$(($1 * -1))"
하지만 이는 부호 없는 양수를 생성하지만 부호 있는 반환 값이 필요합니다.
"$((-1 * -1))" == 1 # but I need '+1'
내 현재 버전은 다음과 같습니다
# Reverts the +/- operators for an integer argument.
#
# $ polarize -1 # +1
# $ polarize +12 # -12
# $ polarize 2-2 # 2-2
# $ polarize - 1 # - 1
#
function polarize() {
[ $# -eq 0 ] && return
if [[ "$@" =~ ^-([[:digit:]]+)$ ]]; then
echo -n "+${BASH_REMATCH[1]}"
elif [[ "$@" =~ ^\+([[:digit:]]+)$ ]]; then
echo -n "-${BASH_REMATCH[1]}"
else
echo -n "$@"
fi
}
몇 가지 참고사항:
- 함수는 부호 있는 정수만 처리해야 합니다(예:
-1
,+22
, 그러나0
OR 는 아님100
). - 매개변수가 없으면 함수는 아무것도 반환하지 않아야 합니다.
- 함수는 여러 인수를 올바르게 처리해야 합니다(아무 작업도 수행하지 않음).
답변1
사용 printf
:
printf '%+d\n' "$(( -$n ))"
형식 printf
문자열은 %+d
"주어진 인수를 부호 있는 십진 정수로 인쇄"를 의미합니다.
그래서 당신은 다음과 같은 것을 얻을 것입니다
revsign () {
if [ "$#" -eq 1 ] && [[ $1 =~ ^[+-][[:digit:]]+$ ]]; then
printf '%+d\n' "$(( -$1 ))"
fi
}
여러 인수가 주어지거나 부호 있는 정수가 아닌 인수가 주어지면 아무 작업도 수행하지 않습니다.
인수가 여러 개 있거나 단일 인수가 부호 있는 정수가 아닌 경우 인수 전달:
revsign () {
if [ "$#" -eq 1 ] && [[ $1 =~ ^[+-][[:digit:]]+$ ]]; then
printf '%+d\n' "$(( -$1 ))"
elif [ "$#" -gt 0 ]; then
printf '%s\n' "$@"
fi
}
0
주의하고 8진수( 에서와 같이 로 시작하여 작성됨)를 유효한 정수로 허용하지 않으려면 034
정규 표현식을 다음으로 변경하세요.
^[+-][1-9][[:digit:]]*$
답변2
정규식을 사용하고 있으므로 더 좋게 만들 수도 있습니다.
^-([[:digit:]]+)$
기호가 아닌 숫자만 캡처 하면 됩니다 .
두 플래그 중 하나를 캡처하려면 정규식을 다음과 같이 변경하면 됩니다.
^([+-])([0-9]+)$
기호 (
+
또는-
) 는 다음과 같습니다.아니요선택사항(?), 반드시 존재해야 합니다(귀하의 요구사항에 따라).008과 같은 선행 0을 제거하지 마십시오. 오류가 발생합니다.
008: 잘못된 8진수
로 변경:
^([+-])0*([0-9]+)$
공백 및/또는 탭을 허용할 수 있는지 설명에서 명확하지 않습니다. 그렇다면 다음으로 변경하십시오.
^[[:blank:]]*([+-])0*([0-9]+)$
그런 다음 올바른 숫자를 다음에서 재구성할 수 있습니다.
${BASH_REMATCH[1]}${BASH_REMATCH[2]}
또는 간단하게:
${BASH_REMATCH[@]:1:2}
전체 스크립트는 다음과 같습니다:
#! /bin/bash
# Reverts the +/- operators for an integer argument.
#
# $ polarize -1 # +1
# $ polarize +12 # -12
# $ polarize 2-2 # 2-2
# $ polarize - 1 # - 1
#
polarize () {
re='^[[:blank:]]*([+-])0*([[:digit:]]+)$'
[[ $# -ne 1 ]] && return
[[ $1 =~ $re ]] || return
printf '<%+d>' "$(( -${BASH_REMATCH[@]:1:2} ))"
}
for n; do
printf '%s' "testing ==$n=="
polarize "$n"
echo
done
실행 시(값 목록은 테스트 목적으로만 전체 스크립트에 유효하며 함수는 하나의 인수만 허용합니다)(0, 100 및 일부 다른 테스트에는 출력이 없습니다):
$ ./testbash.sh +1 -1 +22 -12 0 100 2-2 "- 1" +008
testing ==+1==<-1>
testing ==-1==<+1>
testing ==+22==<-22>
testing ==-12==<+12>
testing ==0==
testing ==100==
testing ==2-2==
testing ==- 1==
testing ==+008==<-8>