Kabuk Komut Dosyasında Onaltılıktan Onluya


126

Biri bir kabuk komut dosyasında onaltılık bir sayıyı ondalık sayıya dönüştürmeme yardım edebilir mi?

Örneğin, onaltılık sayıyı bfca3000bir kabuk betiği kullanarak ondalık sayıya dönüştürmek istiyorum . Temelde iki onaltılık sayının farkını istiyorum.

Benim kodum:

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

Çalıştırırken şu hatayı alıyorum:

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

Yanıtlar:


314

Onaltılıktan ondalık sayıya dönüştürmek için, bunu kabukta veya harici bir programla yapmanın birçok yolu vardır:

İle :

$ echo $((16#FF))
255

ile :

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

ile :

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

ile :

$ printf "%d\n" 0xFF
255

ile :

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

ile :

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

ile :

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

ile :

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

ile :

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

1
Ne ? bc, keyfi bir hassas hesaplayıcı dilidir : harici bir komut.
Gilles Quenot

10
Ve bu yüzden ? Sorunuzun anlamını değiştirmeden önce 4 komutumun amacı tam olarak budur.
Gilles Quenot

2
printfçözüm POSIX? Evetse, en iyisi :)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

3
Bash'de , açıkça daha genel olmasına rağmen $((0xff)), yani C benzeri onaltılık öneki yerine kullanabilirsiniz . 16#N#
Ruslan

3
İlk bash örneği, tamsayı taşma hatasına karşı hassastır, örneğin echo $((077E9F2DBF49D100001#FF)), 2 ^ 64 olan 64 bitlik tamsayı sınırını aşar. bcbunu düzgün bir şekilde hallediyor.
roblogic

39

Linux'ta çok hafif yerleşik bir busybox sürümüyle uğraşmak, geleneksel komutların çoğunun kullanılamadığı anlamına gelir (bc, printf, dc, perl, python)

echo $((0x2f))
47

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

Bu çözüm için Peter Leung'a teşekkür edin.


1
Tamam, ancak tamsayı taşma hatasına dikkat edin, örneğin echo $((0x077E9F2DBF49D100001))2 ^ 64 olan 64 bitlik tamsayı sınırını aşıyor. bcbunu düzgün bir şekilde ele alıyor
roblogic

13

Kabuğu kullanarak yapmanın bir yolu daha (bash veya ksh, tire ile çalışmaz):

echo $((16#FF))
255

#Sembol ne anlama geliyor? Kullanımı hakkında daha fazla bilgi almak için başka uygulamalar veya belgeler var mı?
user1527227

1
Burada bahsediliyor: bağlantı . Bölüm 6.5'in sonunda şöyle diyor: "... sayılar [taban #] n biçimini alır, burada isteğe bağlı taban aritmetik tabanı temsil eden 2 ile 64 arasında bir ondalık sayıdır ve n, bu tabandaki bir sayıdır. taban # atlanır, ardından 10 tabanı kullanılır. 9'dan büyük rakamlar bu sırayla küçük harfler, büyük harfler, '@' ve '_' ile temsil edilir. Taban 36'dan küçük veya 36'ya eşitse, 10 ile 35 arasındaki sayıları temsil etmek için küçük ve büyük harfler birbirinin yerine kullanılabilir. "
Tomás Fox

11

Bir kabuk içinde size çeşitli araçlar mevcuttur. Sputnick, ilk sorunuza dayanarak size seçenekleriniz hakkında mükemmel bir genel bakış sundu. Size birden fazla doğru cevap vermek için harcadığı zaman için kesinlikle oyları hak ediyor.

Listesinde olmayan bir tane daha:

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

Ancak tek yapmak istediğiniz şey çıkarmaksa, neden girdiyi 10 tabanına değiştirmeye çalışasınız?

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

dcKomut "masa kalk" dir. Aynı zamanda stdin'den girdi alacak bc, ancak "işlem sırası" yerine yığınlama ("ters Lehçe") gösterimini kullanır. Bir yığına eklediği girdileri verirsiniz, ardından ona öğeleri yığından çıkaran ve sonuçları geri iten operatörler verirsiniz.

Yukarıdaki komutlarda aşağıdakilere sahibiz:

  • 16i- dc'ye 16 tabanındaki (onaltılık) girişi kabul etmesini söyler. Çıktı tabanını değiştirmez.
  • BFCA3000 - ilk numaranız
  • 17FF - ilk sayınızdan çıkarmak için seçtiğim rastgele bir onaltılık sayı
  • - - ittiğimiz iki sayıyı alın ve sonrakini öncekinden çıkarın, ardından sonucu yığına geri itin
  • p- yığındaki son öğeyi yazdırın. Bu yığını değiştirmez, bu yüzden ...
  • 10o - dc'ye çıktısını "10" tabanına yazdırmasını söyler, ancak girdi numaralandırma şemamızın şu anda onaltılık olduğunu, bu nedenle "10" un "16" anlamına geldiğini unutmayın.
  • p - yığındaki son öğeyi tekrar yazdırın ... bu sefer onaltılık olarak.

DC ile inanılmaz derecede karmaşık matematik çözümleri oluşturabilirsiniz. Araç kutunuzda kabuk betikleri için olması iyi bir şey.


3

Rapor edilen hata, değişkenler boş (veya boş) olduğunda ortaya çıkar:

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

Bu, bc'ye verilen değerin yanlış olması nedeniyle olabilir. Bu, bc'nin BÜYÜK harf değerlerine ihtiyacı olabilir. İhtiyacı var BFCA3000, değil bfca3000. Bu, bash'ta kolayca sabitlenir, yalnızca ^^genişletmeyi kullanın :

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

Bu, senaryoyu şuna değiştirecek:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

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

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

echo "Diference $var5"

Ancak bash, çeviri ve çıkarmayı doğrudan gerçekleştirebileceği için bc [1] kullanmaya gerek yoktur:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

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

echo "Diference $var5"

[1] Not: Fark, orijinal betiğinizde bash ile hesaplandığından, değerlerin 64 bit matematik ile temsil edilebileceğini varsayıyorum. Bash, 64 bit olarak derlenmişse ((2 ** 63) -1) 'den küçük tamsayılarla sınırlıdır. Böyle bir limiti olmayan bc ile tek fark bu olacaktır.


3

Kısa çizgi ve diğer mermilerde kullanabilirsiniz

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

onaltılık bir sayıyı onluk tabana dönüştürmek için. Bu bash veya ksh'ye özgü değildir.


1
örneğinprintf "%d" 0xff
lashgar
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.