Ondalıktan hexa BASH taban dönüşümü


29

Bash, nasıl yaptığını bir ondalık taban dönüşüm yapmak için başka baz, özellikle onaltılık. Diğer tarafa gitmek kolay görünüyor:

$ echo $((16#55))
85

Bir web-arama ile, dönüşüm yapmak için matematik ve karakter manipülasyonunu yapan bir komut dosyası buldum ve bunu bir işlev olarak kullanabilirdim, ama bash'ın zaten yerleşik bir temel dönüşümü olacağını düşünmüştüm. yapar?


Yanıtlar:


35

İle bash(veya herhangi bir kabuk, printfkomutun kullanılabilir olması koşuluyla (genellikle kabuklara yerleştirilmiş standart bir POSIX komutu)):

printf '%x\n' 85

İle zshşunları da yapabilirsiniz:

dec=85
hex=$(([##16]dec))

Bu, 2'den 36'ya kadar olan bazlar için işe 0-9a-zyarar ( rakam olarak büyük / küçük harfe duyarsız).

Ile ksh93kullanabilirsiniz:

dec=85
base54=$(printf %..54 "$dec")

Hangi 2 ile 64 arası bazlar için çalışır ( 0-9a-zA-Z@_rakamlarla).

İle kshve zshde vardır:

$ typeset -i34 x=123; echo "$x"
34#3l

Bu, ksh88’de 36’ya, zsh ve pdksh’ye, ksh93’de ise 64’e kadar sınırlı.

Tüm bunların longsisteminizdeki tamsayıların boyutuyla sınırlı olduğunu unutmayın ( intbazı kabuklarla birlikte). Daha büyük bir şey için, bcveya kullanabilirsiniz dc.

$ echo 'obase=16; 9999999999999999999999' | bc
21E19E0C9BAB23FFFFF
$ echo '16o 9999999999999999999999 p' | dc
21E19E0C9BAB23FFFFF

POSIX'in gerektirdiği 2 ila bir sayı arasında değişen desteklenen tabanların en az 99 olduğu kadar yüksek olması. 16'dan büyük olan tabanlar için 9'dan büyük sayılar boşlukla ayrılmış 0 basamaklı ondalık sayılar olarak gösterilir.

$ echo 'obase=30; 123456' | bc
 04 17 05 06

Ya da dc( bceskiden beri (ve hala bazı sistemlerde) bir sarmalayıcı olmak için dc)

$ echo 30o123456p | dc
 04 17 05 06

Teşekkürler. Tam olarak aradığım şeydi. (Ve utanç verici derecede basit.)
Dave Rove

Ya ile belirleyebileceğiniz keyfi bir temel oluşturmak istiyorsanız #?
flarn2006

@ flarn2006. İle bashbuiltins yapabilirsiniz girdi diğer bazlar için 8, 10 ve 16 dışında herhangi bir baz herhangi tabanında sayılar, ancak çıkış, sen gibi başka kabuk gerekiyordu zshya kshveya kullanım bc/dc.
Stéphane Chazelas 27:16

1
@ StéphaneChazelas Gerçekten mi? Bu biraz garip. Neredeyse onlar için bir sözdizimi programlamak için çok tembel gibi görünüyor; Herhangi bir temelde çıktı alma fikrini, eğer giriş yaptılarsa akıllarından geçmedi.
flarn2006

alias hex="printf '%x\n'"
mwfearnley

5

Printf kullan:

$ printf "%d %x\n" $((16#55)) $((10#85))
85 55

Değeri değişkene atamak için komut değiştirme işlevini kullanın:

$ x=$( printf "%x" 85 ) ; echo $x
55

4
Veya, -vyerleşik printf seçeneğini kullanın :printf -v foo "%d" $((16#BEEF)); echo $foo
glenn jackman

@Glenn -vBurada standart olmayan seçeneklerin (gibi ) kullanılması gereksizdir; Bundan kaçınırdım.
Janis

3
-vçataldan ve borudan kaçınır (bash, burada olduğu gibi çatal olmayacak ksh93 değil printf). Bunun $((16#55))standart olmadığını da unutmayın.
Stéphane Chazelas

@ StéphaneChazelas, bir dakika bekleyin. Ksh93'ün çatallanmadığını mı söylüyorsun x=$(some_builtin)?
glenn jackman

1
@glennjackman, evet, yalnızca harici komutları yerine getirmesi için çatal.
Stéphane Chazelas

2

Bugünlerde oldukça evrensel olan tüm POSIX uyumlu mermilerde bulunan yerleşik Aritmetik Genişletme değiştirmeyi kullanın.

$ echo $((0xbc))
188

ve

$ hex=dead
$ dec=$((0x$hex))
$ echo $dec
57005

DİKKAT: Özellikle son örnekte, genişleme beklenmeyen sonuçlara neden olabilir - 'hex' değişkenindeki onaltılık basamaklar yasal bir onaltılık sabit oluşturmak zorundadır, aksi halde belirsiz hata mesajları oluşur. Örneğin, 'hex' '0xdead' olsaydı, aritmetik genişleme, sabit olarak yorumlanamayan 0x0xdead olur. Tabii ki, bu durumda aritmetik genişleme $ (($ hex)) hile yapardı. Okuyucunun, isteğe bağlı bir '0x' önekini kaldıracak basit alt dize işleme deseni eşlemesi oluşturması için bir alıştırma olarak bırakılmıştır.


4
OP'nin örneğinde de aynısını yapıyorsunuz; Tersine ameliyatı arıyor .
Thomas Guyot-Sionnest

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.