シェルスクリプトで16進数から10進数へ


126

誰かがシェルスクリプトで16進数を10進数に変換するのを手伝ってくれる?

たとえば、bfca3000シェルスクリプトを使用して、16進数を10 進数に変換したいとします。基本的に、2つの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/...
チロ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
あるprintfソリューションは、POSIX?はいの場合、それが最善です:)
Ciro Santilli郝海东冠状病六四事件法轮功

3
明らかにより一般的ですが、bashではを使用することもできます$((0xff))。つまり、の代わりにCのような16進数プレフィックスを使用します。16#N#
Ruslan

3
最初のbashの例は整数オーバーフローエラーの影響を受けやすく、たとえばecho $((077E9F2DBF49D100001#FF))64ビット整数の制限である2 ^ 64をオーバーフローします。bcこれを適切に処理します。
ブログの

39

Linuxでbusyboxの非常に軽量な埋め込みバージョンを処理することは、従来のコマンドの多くが使用できないことを意味します(bc、printf、dc、perl、python)。

echo $((0x2f))
47

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

このソリューションの功績はPeter Leung氏にあります。


1
OKですが、整数オーバーフローエラーに注意してください。たとえばecho $((0x077E9F2DBF49D100001))、64ビットの整数制限である2 ^ 64をオーバーフローします。bcこれを適切に処理します
roblogic

13

シェルを使用してそれを行うもう1つの方法(bashまたはksh、ダッシュでは機能しません):

echo $((16#FF))
255

何をしない#記号の意味は?その使用についてもっと読むための他のアプリケーションやドキュメントはありますか?
user1527227 14

1
ここで言及されています:リンク。セクション6.5の終わりには、次のように記載されています。 base#が省略されている場合は、base 10が使用されます。9より大きい数字は、小文字、大文字の「@」、「_」の順で表されます。baseが36以下の場合、小文字と大文字は、10〜35の数字を表すために互換的に使用できます。」
トマスフォックス14

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」です。も同様bcにstdinから入力を受け取りますが、「操作の順序」を使用する代わりに、スタッキング(「逆ポーランド」)表記を使用します。スタックに追加する入力を与え、スタックからアイテムをポップし、結果を押し戻す演算子を与えます。

上記のコマンドには、次のものがあります。

  • 16i-基数16(16進数)で入力を受け入れるようにdcに指示します。出力ベースを変更しません。
  • BFCA3000 -あなたの最初の番号
  • 17FF -私があなたの最初の数から引くために選んだランダムな16進数
  • - -プッシュした2つの数値を取り、前の数値から後の数値を差し引き、結果をスタックに戻します
  • p-スタックの最後の項目を印刷します。これはスタックを変更しないので...
  • 10o -出力をベース「10」で出力するようにdcに指示しますが、入力の番号付けスキームは現在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ビットの数学で表すことができると想定しています。64ビットでコンパイルした場合、bashは((2 ** 63)-1)未満の整数に制限されます。そのような制限のないbcとの唯一の違いになります。


3

ダッシュおよびその他のシェルでは、

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

16進数を10進数に変換します。これはbashやksh固有ではありません。


1
printf "%d" 0xff
ラッシュガー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.