내 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에는 printf
1000 기반 단위와 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
표준 입력에 표현식을 제공해야 합니다. 이제 다른 많은 쉘에서 발견됨) 명령 대체를 사용하여 파이프를 통해 출력을 얻습니다(예: 변수에 저장) .printf
sh
total
scale
그러나 나눌 때 밑수 뒤에 몇 자릿수를 셀지 알려주기 위해 특수 변수를 설정해야 합니다 ( -l
해당 옵션을 사용하지 않는 한 기본값은 0이며, 이 경우 20입니다). 그래서:
total=$(
printf 'scale=2\n%d / 1000000\n' "$bytes" | bc
)
또는:
total=$(
bc << EOF
scale=2
$bytes / 1000000
EOF
)
또 다른 방법 은 부동 소수점 연산을 수행하고 숫자를 고유한 형식으로 형식화할 수 있다는 bc
것입니다 .awk
printf
total=$(
jq... | awk '{printf "%gMB", $0 / 1e6}'
)
1 echo
도 일반적으로 사용되지만이식성이 없고 신뢰할 수 없는 API를 가지고 있으므로 일반적인 경우에는 임의의 데이터를 출력하지 않는 것이 가장 좋습니다.
답변2
나는 당신이 찾고 있다고 생각합니다 total=$(echo "$bytes / 1000000 " | bc)
.