쉘 스크립트에서 16 진수를 16 진수로


126

쉘 스크립트에서 16 진수를 10 진수로 변환하는 것을 도와 줄 수 있습니까?

예를 들어, bfca3000쉘 스크립트를 사용하여 16 진수 를 10 진수로 변환하고 싶습니다 . 나는 기본적으로 두 개의 16 진수의 차이를 원합니다.

내 코드는 다음과 같습니다

var3=`echo "ibase=16; $var1" | bc`
var4=`echo "ibase=16; $var2" | bc`
var5=$(($var4-$var3))               # [Line 48]

실행할 때이 오류가 발생합니다.

Line 48: -: syntax error: operand expected (error token is "-")

주변의 다른 방법 : stackoverflow.com/questions/378829/... . 본질적으로 동일한 도구입니다. 교차 사이트 복제 : superuser.com/questions/226163/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

답변:


314

16 진수에서 10 진수로 변환하려면 쉘이나 외부 프로그램을 사용하여 여러 가지 방법으로 수행 할 수 있습니다.

:

$ echo $((16#FF))
255

:

$ echo "ibase=16; FF" | bc
255

:

$ perl -le 'print hex("FF");'
255

:

$ printf "%d\n" 0xFF
255

:

$ python -c 'print(int("FF", 16))'
255

:

$ ruby -e 'p "FF".to_i(16)'
255

:

$ nodejs <<< "console.log(parseInt('FF', 16))"
255

:

$ rhino<<EOF
print(parseInt('FF', 16))
EOF
...
255

:

$ groovy -e 'println Integer.parseInt("FF",16)'
255

1
뭐 ? bc는 임의의 정밀 계산기 언어입니다 . 외부 명령입니다.
Gilles Quenot

10
그리고 그래서? 이것은 질문의 의미를 수정하기 전에 내 4 가지 명령의 목적입니다.
Gilles Quenot

2
는 IS printf솔루션 POSIX는? 그렇다면, 최고입니다 :)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

3
bash에서는 $((0xff)), 즉 C 대신 16 진수 접두어 대신을 사용할 수도 16#있지만 N#분명히 더 일반적입니다.
Ruslan

3
첫 번째 bash 예제는 정수 오버 플로우 오류에 취약합니다. 예를 들어 echo $((077E9F2DBF49D100001#FF))64 비트 정수 한계 인 2 ^ 64가 오버 플로우됩니다. bc이것을 올바르게 처리합니다.
roblogic

39

Linux에서 매우 가벼운 임베디드 버전의 busybox를 처리한다는 것은 기존의 많은 명령을 사용할 수 없음을 의미합니다 (bc, printf, dc, perl, python)

echo $((0x2f))
47

hexNum=2f
echo $((0x${hexNum}))
47

신용 피터 렁 이 솔루션.


1
괜찮지 만 정수 오버플로 오류를 조심하십시오. 예를 들어 echo $((0x077E9F2DBF49D100001))64 비트 정수 한도 인 2 ^ 64를 오버플로합니다. bc이것을 올바르게 처리합니다
roblogic

13

쉘을 사용하여 한 가지 더 방법 (bash 또는 ksh는 대시와 작동하지 않음) :

echo $((16#FF))
255

#상징은 무엇을 의미합니까? 사용에 대한 자세한 내용을 읽을 수있는 다른 응용 프로그램이나 설명서가 있습니까?
user1527227

1
여기에 언급되어 있습니다 : link . 섹션 6.5의 끝에 "... 숫자는 [base #] n 형식을 취합니다. 여기서 선택적 밑은 산술 밑을 나타내는 2와 64 사이의 10 진수이고 n은 그 밑의 숫자입니다. 9보다 큰 숫자는 소문자, 대문자 '@'및 '_'의 순서로 표시되며, 밑이 36보다 작거나 같은 경우, 소문자와 대문자는 10과 35 사이의 숫자를 나타 내기 위해 서로 바꿔서 사용할 수 있습니다. "
Tomás Fox

11

쉘 내에서 다양한 도구를 사용할 수 있습니다. Sputnick은 귀하의 초기 질문에 기초하여 귀하의 옵션에 대한 훌륭한 개요를 제공했습니다. 그는 당신에게 여러 가지 정답을 제공하는 시간 동안 투표 할 가치가 있습니다.

그의 목록에없는 것 하나 더 :

[ghoti@pc ~]$ dc -e '16i BFCA3000 p'
3217698816

그러나 당신이하고 싶은 것이 빼기라면, 왜 입력을 밑 10으로 바꾸는 것이 귀찮습니까?

[ghoti@pc ~]$ dc -e '16i BFCA3000 17FF - p 10o p'
3217692673
BFCA1801
[ghoti@pc ~]$ 

dc명령은 "책상 CALC"입니다. 또한 stdin에서 입력을 bc받지만 "연산 순서"를 사용하는 대신 스태킹 ( "역 폴란드어") 표기법을 사용합니다. 스택에 추가하는 입력을 제공 한 다음 스택에서 항목을 팝하는 연산자를 제공하고 결과를 다시 푸시합니다.

위의 명령에는 다음이 있습니다.

  • 16i-16 진수 16 진수로 입력을 받도록 dc에 지시합니다. 출력 기준을 변경하지 않습니다.
  • BFCA3000 -초기 번호
  • 17FF -초기 숫자에서 빼기 위해 선택한 임의의 16 진수
  • - 우리가 누른 두 숫자를 가져 와서 이전 숫자에서 후자를 빼고 결과를 스택으로 다시 밀어 넣습니다.
  • p-스택에 마지막 항목을 인쇄합니다. 이것은 스택을 변경하지 않으므로 ...
  • 10o -dc에 기본 "10"으로 출력을 인쇄하라고 지시하지만 입력 번호 체계는 현재 16 진수이므로 "10"은 "16"을 의미합니다.
  • p -스택의 마지막 항목을 다시 인쇄하십시오. 이번에는 16 진수로 표시하십시오.

dc를 사용하여 엄청나게 복잡한 수학 솔루션을 구성 할 수 있습니다. 쉘 스크립트를 위해 툴박스에있는 것이 좋습니다.


3

변수가 null이거나 비어있는 경우보고 된 오류가 나타납니다.

$ unset var3 var4; var5=$(($var4-$var3))
bash: -: syntax error: operand expected (error token is "-")

bc에 제공된 값이 올바르지 않기 때문에 발생할 수 있습니다. bc는 대문자 값을 필요로 할 수도 있습니다. 필요 BFCA3000하지 않습니다 bfca3000. 그것은 bash에서 쉽게 수정되며 ^^확장을 사용하십시오 .

var3=bfca3000; var3=`echo "ibase=16; ${var1^^}" | bc`

그러면 스크립트가 다음과 같이 변경됩니다.

#!/bin/bash

var1="bfca3000"
var2="efca3250"

var3="$(echo "ibase=16; ${var1^^}" | bc)"
var4="$(echo "ibase=16; ${var2^^}" | bc)"

var5="$(($var4-$var3))"

echo "Diference $var5"

그러나 bash는 번역과 뺄셈을 직접 수행 할 수 있으므로 bc [1]을 사용할 필요가 없습니다.

#!/bin/bash

var1="bfca3000"
var2="efca3250"

var5="$(( 16#$var2 - 16#$var1 ))"

echo "Diference $var5"

[1] 참고 : 원래 스크립트에서 bash로 차이를 계산 했으므로 값을 64 비트 수학으로 표현할 수 있다고 가정합니다. Bash는 64 비트로 컴파일 된 경우 ((2 ** 63) -1)보다 작은 정수로 제한됩니다. 그것은 그러한 제한이없는 bc와의 유일한 차이점이 될 것입니다.


3

대시 및 기타 셸에서 사용할 수 있습니다

printf "%d\n" (your hexadecimal number)

16 진수를 10 진수로 변환합니다. 이것은 bash 또는 ksh가 아닙니다.


1
printf "%d" 0xff
lashgar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.