【问题标题】:Convert decimal to hexadecimal in UNIX shell script在 UNIX shell 脚本中将十进制转换为十六进制
【发布时间】:2010-09-27 14:07:16
【问题描述】:

在 UNIX shell 脚本中,我可以使用什么来将十进制数字转换为十六进制?我以为 od 可以解决问题,但它没有意识到我正在输入数字的 ASCII 表示形式。

打印?总的!目前使用它,但还有什么可用的?

【问题讨论】:

  • 我不得不问,printf 有什么恶心的?许多常见的编程语言都支持类似 printf 的格式,因此下面的 printf 解决方案肯定是开发人员最容易理解的。
  • 孩子,我不知道——那是五年前的事了!我想也许我认为这不是真正的外壳之类的。

标签: unix shell hex


【解决方案1】:

试过printf(1)

printf "%x\n" 34
22

可能有一些方法可以在所有 shell 中使用内置函数,但它的可移植性较差。我还没有检查过 POSIX sh 规范,看看它是否有这样的功能。

【讨论】:

  • 它没有比 printf 更多的 POSIX。这甚至适用于“sh”。
  • printf 不是任意精度。 bc 是。例如,以238862874857408875879219909679752457540 作为输入,printf 给我们“结果太大”。 BC 方法适用于大于标准 int/long/bigint 的事物
  • 而且,如果你想要十六进制的大写字母,请使用 printf "%X" 和大写 X。
  • 要强制输出像“0x00”,你可以使用 printf "0x%02X"
  • ... 和 bc 并非随处可用(至少在我的嵌入式 Linux 上不可用)。
【解决方案2】:

试试:

printf "%X\n" ${MY_NUMBER}

【讨论】:

  • $MY_NUMBER${MY_NUMBER}有什么区别?
  • @SasQ 使用括号强制解释您打算使用的符号,即仅 MY_NUMBER。使用括号可以让您执行诸如 ${MY_TEXT_FRAG_${MY_NUMBER}} 之类的操作来连接变量名称。
【解决方案3】:
echo "obase=16; 34" | bc

如果要过滤整个文件的整数,每行一个:

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

【讨论】:

  • @skiphoppy:如果你写:echo "obase=16; 12 34 56" | bc 你得到 1E240,就像你写的一样: echo "obase=16; 123456" |公元前。因此,在一行上处理任意数量的整数的方法是将每个数字放在自己的行上: tr ' ' '\015'
  • 如果你碰巧有 'bc' 这很好,但 'printf' 是 bash 本身的一部分
  • @Bill Karwin、zsh、busybox,但也许不是我没试过的shell?我不再安装普通的 sh,但显然 skiphoppy 正在寻找其他选项
  • @Sridhar-Sarnobat,这个十进制到十六进制。我假设您的意思是将十六进制转换为十进制。为此,请设置ibase=16。您可能想阅读manual on bc 了解更多详情。
  • 您想添加 bc 区分大小写。意思是echo "ibase=16; dead" | bc 不起作用,你需要做echo "ibase=16; DEAD" | bc,我对此有点惊讶
【解决方案4】:

zsh 你可以做这样的事情:

% typeset -i 16 y
% print $(( [#8] x = 32, y = 32 ))
8#40
% print $x $y
8#40 16#20
% setopt c_bases
% print $y
0x20

示例取自zsh docs page about Arithmetic Evaluation

我相信 Bash 也有类似的能力。

【讨论】:

    【解决方案5】:

    十六进制转十进制:

    $ echo $((0xfee10000))
    4276158464
    

    十进制转十六进制:

    $ printf '%x\n' 26
    1a
    

    【讨论】:

      【解决方案6】:

      对不起,试试这个……

      #!/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}"
      

      例子:

      $ ./dtoh 1024
      400
      

      【讨论】:

      • 感谢这对环境有很大帮助。其中printfhex 命令不可用。
      • @benchuk printf 哪里不可用?
      【解决方案7】:
      bash-4.2$ printf '%x\n' 4294967295
      ffffffff
      
      bash-4.2$ printf -v hex '%x' 4294967295
      bash-4.2$ echo $hex
      ffffffff
      

      【讨论】:

      【解决方案8】:
      # 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
      

      【讨论】:

        【解决方案9】:

        就我而言,我偶然发现了一个使用 printf 解决方案的问题:

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

        最简单的方法是使用带有 bc 的解决方案,在较高的帖子中建议:

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

        【讨论】:

        • 你的解决方案在几年前写的基础上增加了什么?
        • @Matthieu 它提到了带前导零的数字问题,Bash printf 将其解释为八进制,并演示了一种避免该问题的解决方案。
        【解决方案10】:

        这不是 shell 脚本,而是我用来在 bin/oct/dec/hex 之间转换数字的 cli 工具:

            #!/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);
            }
        

        【讨论】:

          【解决方案11】:
          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
          }
          

          【讨论】:

            【解决方案12】:

            哇,我没有意识到 printf 可以在 shell 中使用!

            话虽如此,我很惊讶没有人评论将 printf 放入 shell 脚本(如果需要,您可以将其放入您的个人 bin 目录中)。

            echo "printf"0x%x\n" $1" > 十六进制 chmod +x 十六进制

            现在只需运行: ./十六进制 123

            它返回: 0x7b

            【讨论】:

              猜你喜欢
              • 2013-09-23
              • 2012-10-28
              • 2011-04-04
              • 2016-05-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-07-28
              • 1970-01-01
              相关资源
              最近更新 更多