bash는 문자열이 금액인지 테스트합니다.

bash는 문자열이 금액인지 테스트합니다.

저는 다소 자유로운 형식의 csv 파일로 작업 중이며 비용 항목을 효율적으로 찾아야 합니다. 더 나은 해결책은 각 행의 특정 열 수를 테스트하는 것입니다. 다음을 시도했지만(GNU bash, 버전 5.0.17) 작동하지 않습니다("달러 금액"이 반환되지 않음).

#!/bin/bash
input=$1
if [[ $input == [\$]?[0-9][\,]?[0-9]*[\.]?[0-9]{2}?$ ]]
then
echo "Is a dollar amount"
else
echo "Is NOT a dollar amount"
fi

달러 기호, 쉼표 및 마침표를 (대괄호 없이) 이스케이프 처리해 보았지만 그것도 작동하지 않습니다. 달러 기호가 포함된 인수를 작은따옴표로 묶습니다(필수). ==를 =~로 변경했는데 "달러 금액"이라고 보고된 가능성이 너무 많습니다. 웹에서 비슷한 것을 검색하는 것은 거의 불가능합니다. 내가 뭘 잘못했나요? 나는 내가 쓴 내용이 다음과 같은 의미라고 생각했습니다.

  • 선행 달러 기호는 선택 사항입니다. - [$]?
  • 최소한 한 자리 숫자가 필요합니다 - [0-9]
  • 쉼표는 선택 사항입니다 - [,]?
  • 추가 숫자는 얼마든지 허용됩니다 - [0-9]*
  • 마침표는 선택사항입니다. - [.]?
  • 두 개의 추가 숫자가 있을 수 있지만 이것도 선택 사항입니다. - [0-9]{2}?
  • 마지막 두 자리 뒤에 아무것도 없음 - $

답변1

=~테스트 대신 연산자를 사용하고 싶을 수도 있지만 after는 ==사용할 수 없습니다 .?{2}

"숫자가 없거나 두 자리"라고 말하는 올바른 방법은 입니다 ([0-9]{2})?.

당신이 끝내는 것은

if [[ $input =~ ^\$?[0-9],?[0-9]*\.?([0-9]{2})?$ ]]; then ...; fi

여기에서는 표현식을 줄 시작 부분에 고정 ^하고 불필요한 대괄호도 제거했습니다.

문자열의 선택적 부분이 독립적으로 선택 사항이 아닌 경우 해당 부분을 괄호로 묶어야 할 수도 있습니다. 예를 들어 다음과 같습니다.

if [[ $input =~ ^\$?[0-9](,[0-9]+)?(\.[0-9]{2})?$ ]]; then ...; fi

쉼표가 있는 경우 쉼표 뒤에 최소한 한 자리가 있어야 하고, 점이 있으면 점 뒤에 최소한 두 자리가 있어야 합니다.

답변2

@they의 위 게시물 덕분에 답을 찾았습니다.

if [[ $input =~ ^\$?[0-9]{1,3}(,[0-9]{3})*(\.[0-9]{2})?$ ]]

나는 내가 많은 실수를 했다는 것을 깨달았다. 위의 스크립트를 "테스트"라고 부르고 여러 변형(아래 참조)을 시도했는데 모두 예상대로 응답했습니다.

다음 보고서는 "달러 금액입니다"

  • ./test1
  • ./test75
  • ./test453
  • ./test '$453'
  • ./test1,234
  • ./test1,234.89
  • ./test1,234,657.89

다음 보고서는 "달러 금액이 아님"을 보고합니다.

  • ./test1a234,657.89
  • ./test 1,234.657.89 (두 마침표에 주의하세요)
  • ./test 1,234,657.9(센트 자리 누락)

관련 정보