bc 계산기에서 변수 초기화를 사용자 정의할 수 있는 방법이 있습니까?

bc 계산기에서 변수 초기화를 사용자 정의할 수 있는 방법이 있습니까?

bc 계산기가 초기화되지 않은 변수에 0 값을 할당하는 것 같습니다. bc가 초기화되지 않은 변수를 발견하면 표현식이 유효하지 않은 것으로 표시되도록 이 동작을 변경하고 싶습니다. 예를 들어, 아래 코드에서는

echo "foo + bar" | bc -l

bc는 foo와 bar에 값 0을 할당하고 "0"을 반환합니다. 빈 문자열 ""을 반환하거나 "foo + bar"가 잘못된 표현식임을 나타내기를 원합니다. BC에서 이것을 달성할 수 있는 방법이 있습니까?

답변1

내 질문에 대답하기 위해 bc에서 선언되지 않은 변수를 유효하지 않은 것으로 표시하는 것 외에도 다른 사람에게 유용할 경우를 대비해 작동하는 솔루션을 생각해 냈습니다. bc 실행될 표현식은 먼저 sed 명령을 통해 파이프됩니다. 이 명령은 표현식에서 유지된 bc 단어를 제거합니다. 나머지 변수 이름은 선언되지 않은 변수로 간주되며 전체 표현식은 bc에서 실행될 때 오류를 강제로 발생시키는 명령문으로 변환됩니다. (나는 "1/0"을 선택했지만 오류 플래그 중 어느 것으로든 많은 대안을 구성할 수 있습니다.)

런타임 "0으로 나누기" 오류를 생성합니다.

echo 'foo + bar' | sed -E '
    ## Save the original expression in the hold space
    h
    ## Recursively replace all bc reserved words with a unique token string (¦§§¦)
    :again
    s/auto|break|continue|define|else|for|halt|ibase|if|last|length|limits|obase|print|quit|read|return|scale|sqrt|warranty|while/¦§§¦/g
    s/(a|c|e|j|l|s)([(][^)]*[)])/¦§§¦\2/g
    t again
    ## If the expression contains any bc reserved words abutting one another, mark the expression as invalid, and skip to the end of the sed script
    /¦§§¦¦§§¦/s/^.+$/1\/0/
    t
    ## Replace all tokens with spaces
    s/¦§§¦/ /g
    ## If any variable names remain, treat them as undeclared variables, mark the expression as invalid, and skip to the end of the sed script
    ## Prior to doing this, reset the t command so that it can recognize if a substitution takes place in the s command
    t reset
    :reset
    /[a-z][a-z0-9_]*/s/^.+$/1\/0/
    t
    ## If the expression does not have undeclared variable names, get the original expression from the hold space
    g
' | bc -l

정답 반환 = 246:

echo '123 + 123' | sed -E '
    ## Save the original expression in the hold space
    h
    ## Recursively replace all bc reserved words with a unique token string (¦§§¦)
    :again
    s/auto|break|continue|define|else|for|halt|ibase|if|last|length|limits|obase|print|quit|read|return|scale|sqrt|warranty|while/¦§§¦/g
    s/(a|c|e|j|l|s)([(][^)]*[)])/¦§§¦\2/g
    t again
    ## If the expression contains any bc reserved words abutting one another, mark the expression as invalid, and skip to the end of the sed script
    /¦§§¦¦§§¦/s/^.+$/1\/0/
    t
    ## Replace all tokens with spaces
    s/¦§§¦/ /g
    ## If any variable names remain, treat them as undeclared variables, mark the expression as invalid, and skip to the end of the sed script
    ## Prior to doing this, reset the t command so that it can recognize if a substitution takes place in the s command
    t reset
    :reset
    /[a-z][a-z0-9_]*/s/^.+$/1\/0/
    t
    ## If the expression does not have undeclared variable names, get the original expression from the hold space
    g
' | bc -l

편집자 주: 이는 원래 제출한 내용이 개선되었으며 선언되지 않은 변수 이름을 검색하는 데 더 정확해졌습니다.

답변2

사용을 고려 중이신 expr가요?

$ expr foo + bar
expr: non-integer argument
$ expr 1 + 5
6

관련 정보