给文件及其行号在bash中转换十进制的十六进制数

时间:2017-04-20 16:43:09

标签: linux bash

我的文本文件超过10,000行。在这个文件中,我有一个行号713包含三个十六进制数,如7E 42 C0。我需要将其转换为十进制。如果我只在文本文件中给出这个数字,我的代码效果很好。但是,我想提供该文件的文件和行号

如下所示:

while read p q r; 
  do 

   printf "%d %d %d\n" 0x$p 0x$q 0x$r; 

 done   < $(sed -n '713p' run21.txt);

但它不起作用并给我ambiguous redirect的错误。请让我知道任何解决方案。

3 个答案:

答案 0 :(得分:1)

您走在正确的轨道上,将hex转换为dec使用定义为bcibase的{​​{1}},例如

obase

$ echo "obase=10; ibase=16; $(sed -n 713p run21.txt)" | bc 行的任何hex值都将输出为713。您可以使用decimal读取3个值,并以类似的方式转换每个值。或者,您可以删除3个十六进制值之间的空格,并根据您的要求将其转换为单个十进制值。例如:

read -r a b c

<强>输出

hexval=""
for i in $(sed -n 713p run21.txt); do
    hexval="$hexval$i"
done
echo "obase=10; ibase=16; $hexval" | bc

要单独转换每个,您可以执行以下操作:

8274624

<强>输出

for i in $(sed -n 713p run21.txt); do
    printf " %d" "$(echo "obase=10; ibase=16; $i" | bc)"
done
printf "\n"

作为使转换更加健壮的另一个步骤,您可以(并且应该)添加读取为输入的所有值的验证。您可以对读入每个变量的字符类型进行更多验证,但您至少应验证读取 AND 已填充您期望的值的数量。将它们放在一起,并使用126 66 192 来读取和验证所有3个值,您可以执行以下操作。

该脚本将 line_to_read 作为其第一个必需参数,并将read作为其第二个可选参数读取(默认情况下将从filename读取):< / p>

stdin

示例输入

#!/bin/bash

test -z "$1" && {   ## validate line number given
    printf "error: insufficient input.\nusage: %s line [file (stdin)]\n" "${0##*/}"
    exit 1
}

test "$1" -eq "$1" &>/dev/null || {  ## test $1 is an integer value
    printf "error: first parameter not an integer '%s'\n" "$1"
    exit 1
}

fn="$2" ## read from filename as 2nd parameter (or by default from stdin)
test -f "$fn" || fn=/dev/stdin

read -r a b c < <(sed -n "${1}p" "$fn")     ## read each of the values

test -n "$a" -a -n "$b" -a -n "$c" || {     ## validate all 3 vars filled
    printf "error: less than 3 values on line '%s',\n" "$1"
    exit 1
}

printf "input : %3x %3x %3x\n" "0x$a" "0x$b" "0x$c" ## output original line
## output line converted from hex to decimal
printf "output: %3d %3d %3d\n" $(echo "obase=10; ibase=16; $a" | bc) \
$(echo "obase=10; ibase=16; $b" | bc) $(echo "obase=10; ibase=16; $c" | bc)

示例使用/输出

$ cat dat/3hex.txt
7E 42 C0

答案 1 :(得分:0)

这种方式可能更直接......

read p q r < <(sed -n '713{p;q}' file);  printf "%d %d %d\n" 0x$p 0x$q 0x$r;

答案 2 :(得分:0)

@大卫 我这样做了

while read -r p q r; 
  do 

   #printf "%d %d %d\n" 0x$p 0x$q 0x$r; 
   #printf "%d %d %d\n"
   echo "obase=10; ibase=16; $(sed -n 713p run21.txt)" | bc ;

  done

但没有输出。