기본 계산기의 출력을 변수에 넣을 수 없습니다. bash에서 바이트를 MB로 형식화하십시오.

기본 계산기의 출력을 변수에 넣을 수 없습니다. bash에서 바이트를 MB로 형식화하십시오.

내 Wi-Fi 장치의 데이터 사용량을 상단 표시줄에 표시하고 싶습니다. 다음과 같이 컬을 사용하여 데이터 사용량을 바이트 단위로 가져올 수 있습니다.

$bytes=(curl -d "Page=GetWANInfo" -X POST http://jiofi.local.html/cgi-bin/qcmap_web_cgi -s| jq -r .total_data_used)

지금 처럼 큰 숫자가 나옵니다. 411982397이를 MB로 변환하여 다음과 같이 표시하고 싶습니다.411.9 MB

하지만 이렇게 큰 숫자를 어떻게 형식화할 수 있는지 모르겠습니다.

나는 bc그것을 MB로 변환하려고 시도했다.echo $bytes / 1000000 | bc

하지만 변수에 넣을 수 없어서 오류가 발생합니다.

$ total=($bytes / 1000000 | bc)
bash: syntax error near unexpected token `|'
$ total=$($bytes / 1000000 | bc)
411982397: command not found
$ echo "$bytes / 1000000" | bc
411
$ total=$("$bytes / 1000000" | bc)
bash: 411982397 / 1000000: No such file or directory

내 생각은 출력을 변수에 넣는 것입니다.echo $total MB

이 문제를 해결하는 더 좋은 방법은 무엇입니까? 또한 이 명령을 몇 초마다 실행해야 하므로 쉽게 CPU를 많이 사용하게 될 수 있는 이 문제에 대한 효율적인 솔루션이 필요합니다.

답변1

jq나누기를 할 수 있습니다:

$ echo '{"total_data_used":411982397}' | jq -r '.total_data_used/1e6|tostring + "MB"'
411.982397MB

특별히 bash를 사용할 필요가 없다면 대부분의 최신 쉘(적어도 zsh, ksh93, yash, fish)은 스스로 이 작업을 수행할 수도 있습니다.

zsh에서:

printf -v total %gMB $(( bytes / 1_000_000. ))

( .부동 소수점 연산을 강제하는 것에 주의하세요. 그것도 사용할 수 있습니다 1e6).

ksh93에는 printf1000 기반 단위와 1024 기반 단위를 모두 사용하여 kMGTPE 접미사가 포함된 사람이 읽을 수 있는 형식으로 변환하는 기능도 내장되어 있습니다.

$ printf '%#dB\n' bytes
412MB
$ printf '%#iB\n' bytes
393MiB

특히 bash에서 10의 거듭제곱으로 나누는 특별한 경우에는 이를 정수에 printf추가 하고 , , , ( 또는 대문자 변형)에 대한 인수로 사용하여 사용할 수 있습니다.e-6%e%f%g%a

printf -v total %gMB "${bytes}e-6"

기본 정밀도는 유효 숫자 6자리이지만 원하는 경우 %g정밀도를 예를 들어 12자리로 변경할 수 있습니다 . (적어도 bash 및 zsh에서는) 로케일의 10진수 기본 문자가 존중됩니다 %.12g. printf예를 들어, 영어 로케일에서는 411.982MB, 프랑스어/독일어 로케일에서는 411,982MB를 얻게 됩니다.

나누기를 수행 하려면 출력하는 명령의 출력을 파이핑하거나(일반적으로 이를 위해 사용됨) 문서 here(standard ) 또는 here - string( zsh 에서)을 사용하여 bc표준 입력에 표현식을 제공해야 합니다. 이제 다른 많은 쉘에서 발견됨) 명령 대체를 사용하여 파이프를 통해 출력을 얻습니다(예: 변수에 저장) .printfshtotal

scale그러나 나눌 때 밑수 뒤에 몇 자릿수를 셀지 알려주기 위해 특수 변수를 설정해야 합니다 ( -l해당 옵션을 사용하지 않는 한 기본값은 0이며, 이 경우 20입니다). 그래서:

total=$(
  printf 'scale=2\n%d / 1000000\n' "$bytes" | bc
)

또는:

total=$(
  bc << EOF
scale=2
$bytes / 1000000
EOF
)

또 다른 방법 은 부동 소수점 연산을 수행하고 숫자를 고유한 형식으로 형식화할 수 있다는 bc것입니다 .awkprintf

total=$(
  jq... | awk '{printf "%gMB", $0 / 1e6}'
)

1 echo도 일반적으로 사용되지만이식성이 없고 신뢰할 수 없는 API를 가지고 있으므로 일반적인 경우에는 임의의 데이터를 출력하지 않는 것이 가장 좋습니다.

답변2

나는 당신이 찾고 있다고 생각합니다 total=$(echo "$bytes / 1000000 " | bc).

관련 정보