Chuyển đổi thập phân sang thập lục phân trong tập lệnh shell UNIX


110

Trong tập lệnh shell UNIX, tôi có thể sử dụng gì để chuyển số thập phân thành thập lục phân? Tôi nghĩ od sẽ thực hiện thủ thuật, nhưng nó không nhận ra rằng tôi đang cung cấp cho nó các biểu diễn ASCII của các con số.

printf? Tổng! Sử dụng nó cho bây giờ, nhưng những gì khác có sẵn?


8
Tôi phải hỏi, printf là gì? Nhiều ngôn ngữ lập trình phổ biến hỗ trợ định dạng giống printf, vì vậy các giải pháp printf dưới đây chắc chắn sẽ dễ hiểu nhất đối với các nhà phát triển.
Michael Scheper

4
Chàng trai, tôi không biết - đó là năm năm trước! Tôi nghĩ có lẽ tôi đã nghĩ đó không phải là vỏ thật hay gì đó.
jumphoppy

Câu trả lời:


108
echo "obase=16; 34" | bc

Nếu bạn muốn lọc toàn bộ tệp số nguyên, một tệp trên mỗi dòng:

( echo "obase=16" ; cat file_of_integers ) | bc

1
Tôi đã xem xét cả bc (1) và dc (1) và bỏ lỡ cái đó.
Keltia

3
@skiphoppy: Nếu bạn viết: echo "obase = 16; 12 34 56" | bc bạn nhận được 1E240, giống như khi bạn viết: echo "obase = 16; 123456" | bc. Vì vậy, cách xử lý các số nguyên tùy ý nằm trên một dòng là đặt mỗi số trên dòng riêng của nó: tr '' '\ 015' <input | bc (bản đồ trống sang dòng mới).
Jonathan Leffler

1
Đây là tuyệt vời nếu bạn xảy ra để có 'bc', nhưng 'printf' là một phần của bản thân bash
fuzzyTew

1
@Bill Karwin, hoặc zsh, hoặc busybox, nhưng có lẽ không phải một số shell mà tôi chưa thử? Tôi không giữ sh đồng bằng cài đặt nữa nhưng skiphoppy rõ ràng đang tìm kiếm những tùy chọn khác có
fuzzyTew

2
@ Sridhar-Sarnobat, đây số thập phân đến thập lục phân. Tôi giả sử bạn muốn chuyển đổi hex sang dec. Để làm điều đó, hãy thiết lập ibase=16. Bạn có thể muốn đọc hướng dẫn sử dụng bc để biết thêm chi tiết.
Bill Karwin

186

Đã thử printf(1)?

printf "%x\n" 34
22

Có thể có nhiều cách để làm điều đó với các hàm nội trang trong tất cả các shell nhưng nó sẽ ít di động hơn. Tôi đã không kiểm tra thông số kỹ thuật của POSIX sh để xem liệu nó có khả năng như vậy hay không.


5
Nó không nhận được nhiều POSIX hơn printf. Điều này thậm chí hoạt động trong "sh".
Orwellophile

4
printf không phải là độ chính xác thuộc tính. bcLà. ví dụ, lấy 238862874857408875879219909679752457540làm đầu vào, printf cho chúng ta "Kết quả quá lớn". phương pháp BC hoạt động tuyệt vời cho những thứ lớn hơn một int / dài / bigint chuẩn
Andrew Backer

3
Và, nếu bạn muốn chữ hoa trong hex, sử dụng printf "%X"với chữ hoa X.
andrybak

3
Và để buộc một đầu ra như "0x00", bạn có thể sử dụng printf "0x% 02X"
gbetous

1
... và bckhông có sẵn ở mọi nơi (ít nhất là không có trên Linux nhúng của tôi).
Matthieu

69

Hệ thập phân từ hệ thập phân sang thập phân:

$ echo $((0xfee10000))
4276158464

Từ thập phân sang thập lục phân:

$ printf '%x\n' 26
1a

15
bash-4.2$ printf '%x\n' 4294967295
ffffffff

bash-4.2$ printf -v hex '%x' 4294967295
bash-4.2$ echo $hex
ffffffff

1
-v VARlà một phần mở rộng bash. Không được đề cập trong trang người đàn ông , tiết lộ chỉ khi một cuộc gọi printfmà không cần lý lẽ
Adrian W

5

Xin lỗi lỗi của tôi, hãy thử cái này ...

#!/bin/bash
:

declare -r HEX_DIGITS="0123456789ABCDEF"

dec_value=$1
hex_value=""

until [ $dec_value == 0 ]; do

    rem_value=$((dec_value % 16))
    dec_value=$((dec_value / 16))

    hex_digit=${HEX_DIGITS:$rem_value:1}

    hex_value="${hex_digit}${hex_value}"

done

echo -e "${hex_value}"

Thí dụ:

$ ./dtoh 1024
400

1
Cảm ơn điều này đã giúp rất nhiều cho env. ở đâu printfhexcác lệnh không có sẵn.
băng ghế dự bị

2
@benchuk printfkhông có ở đâu?
Matthieu



2

Trong trường hợp của tôi, tôi đã gặp một vấn đề khi sử dụng giải pháp printf:

$ printf "%x" 008 bash: printf: 008: invalid octal number

Cách dễ nhất là sử dụng giải pháp với bc , được đề xuất trong bài đăng cao hơn:

$ bc <<< "obase=16; 008" 8


Giải pháp của bạn bổ sung gì cho những giải pháp được viết nhiều năm trước?
Matthieu

@Matthieu Nó đề cập đến vấn đề của các số với các số 0 ở đầu, mà Bash printf giải thích một cách vô ích là số bát phân và giải thích một giải pháp tránh được vấn đề.
mwfearnley 21/10/19

2
xd() {
    printf "hex> "
    while read i
    do
        printf "dec  $(( 0x${i} ))\n\nhex> "
    done
}
dx() {
    printf "dec> "
    while read i
    do
        printf 'hex  %x\n\ndec> ' $i
    done
}

1
# number conversion.

while `test $ans='y'`
do
    echo "Menu"
    echo "1.Decimal to Hexadecimal"
    echo "2.Decimal to Octal"
    echo "3.Hexadecimal to Binary"
    echo "4.Octal to Binary"
    echo "5.Hexadecimal to  Octal"
    echo "6.Octal to Hexadecimal"
    echo "7.Exit"

    read choice
    case $choice in

        1) echo "Enter the decimal no."
           read n
           hex=`echo "ibase=10;obase=16;$n"|bc`
           echo "The hexadecimal no. is $hex"
           ;;

        2) echo "Enter the decimal no."
           read n
           oct=`echo "ibase=10;obase=8;$n"|bc`
           echo "The octal no. is $oct"
           ;;

        3) echo "Enter the hexadecimal no."
           read n
           binary=`echo "ibase=16;obase=2;$n"|bc`
           echo "The binary no. is $binary"
           ;;

        4) echo "Enter the octal no."
           read n
           binary=`echo "ibase=8;obase=2;$n"|bc`
           echo "The binary no. is $binary"
           ;;

        5) echo "Enter the hexadecimal no."
           read n
           oct=`echo "ibase=16;obase=8;$n"|bc`
           echo "The octal no. is $oct"
           ;;

        6) echo "Enter the octal no."
           read n
           hex=`echo "ibase=8;obase=16;$n"|bc`
           echo "The hexadecimal no. is $hex"
           ;;

        7) exit 
        ;;
        *) echo "invalid no." 
        ;;

    esac
done

1

Đây không phải là một tập lệnh shell, nhưng nó là công cụ cli mà tôi đang sử dụng để chuyển đổi số giữa các bin / oct / dec / hex:

    #!/usr/bin/perl

    if (@ARGV < 2) {
      printf("Convert numbers among bin/oct/dec/hex\n");
      printf("\nUsage: base b/o/d/x num num2 ... \n");
      exit;
    }

    for ($i=1; $i<@ARGV; $i++) {
      if ($ARGV[0] eq "b") {
                    $num = oct("0b$ARGV[$i]");
      } elsif ($ARGV[0] eq "o") {
                    $num = oct($ARGV[$i]);
      } elsif ($ARGV[0] eq "d") {
                    $num = $ARGV[$i];
      } elsif ($ARGV[0] eq "h") {
                    $num = hex($ARGV[$i]);
      } else {
                    printf("Usage: base b/o/d/x num num2 ... \n");
                    exit;
      }
      printf("0x%x = 0d%d = 0%o = 0b%b\n", $num, $num, $num, $num);
    }
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.