awk를 사용하여 0 예외로 나누기

awk를 사용하여 0 예외로 나누기

var1=6, var2=4 변수에 값을 저장하고 정밀도 2로 나누어서 그 결과를 변수에 저장하려고 하는데 var,

var=`awk 'BEGIN {printf "%.2f\n", $var1/ $var2}'`

위의 작업을 수행하면 awk: cmd. line:1: fatal: division by zero attempted

누군가 내가 여기서 정확히 무엇을 놓치고 있는지 지적할 수 있습니까?

감사해요!

답변1

-v var=valueawk에 변수를 전달하는 데 사용됩니다 .

그러므로

awk -v var1="$var1" -v var2="$var2" 'BEGIN {printf "%.2f\n",var1/var2}'

주다

1.50

그리고

var=$(awk -v var1="$var1" -v var2="$var2" 'BEGIN {printf "%.2f\n",var1/var2}') 

값을 설정합니다.

당신은해야합니다

  • -v var1="$var1"bash의 $var1을 awk의 var1로 변환
  • var1다음에서 사용 awk(필수는 아님 $, $var1var1=6이 $6값임)
  • echo입력 제공 awk(그렇지 않으면 awk가 입력을 기다리며 중단됨) (awk에서 BEGIN을 잊어버림)

답변2

$var1여기에서 및의 내용을 전달할 수 있습니다.$var2 껍데기awk변수를 스크립트의 매개변수 로 사용 하고 특수 배열 변수를 통해 스크립트에서 해당 변수에 액세스합니다 ARGV.

var=$(awk -- 'BEGIN {printf "%.2f", ARGV[1] / ARGV[2]}' "$var1" "$var")

또는 변수를 내보내고 셸할 수 var1있습니다 var2.환경배열 변수를 통해 awk검색 하려면 다음을 수행하세요.ENVIRON

var=$(
  export var1 var2
  awk 'BEGIN {printf "%.2f", ENVIRON["var1"] / ENVIRON["var2"]}'
)

ARGV일반적인 경우에는 / ENVIRONover -v또는 인수를 사용하여 임의의 데이터를 전달하는 것이 일반적으로 더 좋습니다 var=value. 후자는 백슬래시 문자를 깨뜨릴 수 있기 때문입니다(물론 숫자에는 실제로 문제가 되지 않지만).

코드 매개변수에 셸 변수 확장을 포함시키는 것은 awk코드 주입 취약점을 야기하므로 피해야 합니다. 다음에도 적용됩니다.매개변수에 매개변수 확장을 인용하는 것을 잊었습니다.-v.

쉘이 또는 다음인 경우에는 이것이 ksh93전혀 필요하지 않습니다 zsh.awk

printf -v var %.2f '1.*var1 / var2' # zsh
var=${ printf %.2f '1.*var1 / var2'; } # ksh93

(AND를 곱하면 1.계산이 부동 소수점 형식으로 수행됩니다.)

그러나 당신이 필요하다는 점에 유의하십시오.이 변수의 내용을 정리하세요. 그렇지 않으면 또 다른 임의 코드 실행 취약점이 됩니다.이러한 변수의 내용이 귀하의 통제하에 있지 않은 경우.

답변3

이는 이와 같은 간단한 스크립트에는 문제가 있지만 실제로 사용하려는 경우 awk더 복잡한 스크립트에는 적합합니다 . 이에 대해 다음 두 가지 방법으로 해결할 수 있습니다.

  1. 간단한 따옴표를 큰 따옴표로 바꾸십시오. 달러 확장을 막는 간단한 방법. 이로 인해 기존 큰따옴표를 이스케이프해야 하는 필요성과 같은 다른 문제가 발생하고, awk내에서 필드를 사용하려는 경우에도 동일한 요구 사항이 발생합니다.

    var=`awk "BEGIN {printf \"%.2f\n\", $var1/ $var2}"`
    
  2. 변수를 awk올바른 방법으로 전달하십시오.

    var=$(awk -v var1="$var1" var2="$var2" 'BEGIN {printf("%`.2f\n",var1,var2)}')
    

관련 정보