Hệ thập lục phân đến số thập phân trong Shell Script


126

Ai đó có thể giúp tôi chuyển đổi số thập lục phân thành số thập phân trong tập lệnh shell không?

Ví dụ, tôi muốn chuyển đổi số thập lục phân thành số bfca3000thập phân bằng cách sử dụng tập lệnh shell. Về cơ bản tôi muốn sự khác biệt của hai số thập lục phân.

Mã của tôi là:

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

Khi thực thi, tôi gặp lỗi này:

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

Cách khác: stackoverflow.com/questions/378829/ trên . Về cơ bản là các công cụ tương tự. Và có thể trùng lặp trang web chéo của: superuser.com/questions/226163/
Ấn

Câu trả lời:


314

Để chuyển đổi từ hex sang thập phân, có nhiều cách để thực hiện trong shell hoặc với một chương trình bên ngoài:

Với :

$ echo $((16#FF))
255

với :

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

với :

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

với :

$ printf "%d\n" 0xFF
255

với :

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

với :

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

với :

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

với :

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

với :

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

1
Gì ? bc là một ngôn ngữ máy tính chính xác tùy ý : một lệnh bên ngoài.
Gilles Quenot

10
Và vì thế ? đây chính xác là mục đích của 4 lệnh của tôi trước khi bạn sửa đổi ý nghĩa câu hỏi của bạn.
Gilles Quenot

2
printfgiải pháp POSIX? Nếu có, đó là điều tốt nhất :)
Ciro Santilli 冠状 病 六四 事件

3
Trong bash, bạn cũng có thể sử dụng $((0xff)), tức là với tiền tố hex giống như C thay vì 16#, mặc dù N#rõ ràng là tổng quát hơn.
Ruslan

3
Ví dụ bash đầu tiên dễ bị lỗi tràn số nguyên, ví dụ echo $((077E9F2DBF49D100001#FF))vượt quá giới hạn số nguyên 64 bit là 2 ^ 64. bcxử lý việc này đúng cách.
roblogic

39

Xử lý một phiên bản busybox nhúng rất nhẹ trên Linux có nghĩa là nhiều lệnh truyền thống không khả dụng (bc, printf, dc, perl, python)

echo $((0x2f))
47

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

Tín dụng cho Peter Leung cho giải pháp này.


1
OK nhưng hãy cẩn thận với lỗi tràn số nguyên, ví dụ: echo $((0x077E9F2DBF49D100001))vượt quá giới hạn số nguyên 64 biit là 2 ^ 64. bcxử lý việc này đúng cách
roblogic

13

Một cách khác để làm điều đó bằng cách sử dụng shell (bash hoặc ksh, không hoạt động với dấu gạch ngang):

echo $((16#FF))
255

Không những gì #biểu tượng nghĩa là gì? Có bất kỳ ứng dụng hoặc tài liệu nào khác để đọc thêm về việc sử dụng nó không?
dùng1527227

1
Nó được đề cập ở đây: liên kết . Ở cuối phần 6.5 có ghi: "... các số có dạng [cơ sở #] n, trong đó cơ sở tùy chọn là số thập phân từ 2 đến 64 đại diện cho cơ sở số học và n là một số trong cơ sở đó. Nếu cơ sở # bị bỏ qua, sau đó cơ sở 10 được sử dụng. Các chữ số lớn hơn 9 được biểu thị bằng các chữ cái viết thường, các chữ cái in hoa, '@' và '_', theo thứ tự đó. Nếu cơ sở nhỏ hơn hoặc bằng 36, chữ thường và chữ in hoa có thể được sử dụng thay thế cho nhau để biểu thị các số từ 10 đến 35. "
Tomás Fox

11

Công cụ khác nhau có sẵn cho bạn từ trong một vỏ. Sputnick đã cung cấp cho bạn một cái nhìn tổng quan tuyệt vời về các lựa chọn của bạn, dựa trên câu hỏi ban đầu của bạn. Anh ấy chắc chắn xứng đáng được bình chọn cho thời gian anh ấy dành cho bạn nhiều câu trả lời đúng.

Một điều nữa không có trong danh sách của anh ấy:

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

Nhưng nếu tất cả những gì bạn muốn làm là trừ đi, tại sao lại phải thay đổi đầu vào thành cơ sở 10?

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

Các dclệnh là "bàn calc". Nó cũng sẽ lấy đầu vào từ stdin, như bc, nhưng thay vì sử dụng "thứ tự các thao tác", nó sử dụng ký hiệu xếp chồng ("Ba Lan ngược"). Bạn cung cấp cho nó đầu vào mà nó thêm vào một ngăn xếp, sau đó cung cấp cho nó các toán tử bật các mục ra khỏi ngăn xếp và đẩy lùi kết quả.

Trong các lệnh trên, chúng tôi đã có những điều sau đây:

  • 16i- bảo dc chấp nhận đầu vào trong cơ sở 16 (thập lục phân). Không thay đổi cơ sở đầu ra.
  • BFCA3000 - số ban đầu của bạn
  • 17FF - một số hex ngẫu nhiên tôi đã chọn để trừ đi số ban đầu của bạn
  • - - lấy hai số chúng tôi đã đẩy và trừ số sau từ số trước, sau đó đẩy kết quả trở lại vào ngăn xếp
  • p- in mục cuối cùng trên ngăn xếp. Điều này không thay đổi ngăn xếp, vì vậy ...
  • 10o - yêu cầu dc in đầu ra của nó trong cơ sở "10", nhưng hãy nhớ rằng sơ đồ đánh số đầu vào của chúng tôi hiện là thập lục phân, vì vậy "10" có nghĩa là "16".
  • p - in mục cuối cùng trên ngăn xếp một lần nữa ... lần này là hex.

Bạn có thể xây dựng các giải pháp toán học phức tạp tuyệt vời với dc. Đó là một điều tốt để có trong hộp công cụ của bạn cho các kịch bản shell.


3

Lỗi như báo cáo xuất hiện khi các biến là null (hoặc trống):

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

Điều đó có thể xảy ra vì giá trị được trao cho bc là không chính xác. Đó cũng có thể là bc cần các giá trị UPPERcase. Nó cần BFCA3000, không phải bfca3000. Điều đó dễ dàng được sửa trong bash, chỉ cần sử dụng ^^mở rộng:

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

Điều đó sẽ thay đổi tập lệnh này:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

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

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

echo "Diference $var5"

Nhưng không cần sử dụng bc [1], vì bash có thể thực hiện dịch trực tiếp và cơ chất:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

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

echo "Diference $var5"

[1] Lưu ý: Tôi giả sử các giá trị có thể được biểu diễn trong toán học 64 bit, vì sự khác biệt được tính bằng bash trong tập lệnh gốc của bạn. Bash bị giới hạn ở số nguyên nhỏ hơn ((2 ** 63) -1) nếu được biên dịch thành 64 bit. Đó sẽ là sự khác biệt duy nhất với bc không có giới hạn như vậy.


3

Trong dấu gạch ngang và các shell khác, bạn có thể sử dụng

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

để chuyển đổi một số thập lục phân thành số thập phân. Đây không phải là bash, hoặc ksh, cụ thể.


1
ví dụprintf "%d" 0xff
lashgar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.