unix Bash字符串,十六进制到十进制

ovfsdjhp  于 2023-10-18  发布在  Unix
关注(0)|答案(6)|浏览(163)

我已经与一些类似的问题作斗争,我相信已经讨论过了,但我真的找不到出路:如果你的文件有数据,例如下面(十六进制值可以是任何东西,但固定为1字节),你想转换每个十六进制到十进制,并保持它在下面的格式,而不是十六进制,你显示十进制,仍然逗号分隔?- 请注意,数据线的数量不是固定的,它可以由任何数量。
例一:

0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a
0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0
0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a
0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0
0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51
0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a
0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0

示例2:与上面相同,但假设它前面有数据名称:

X:0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51
Y:0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a
Z:0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0
X:0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51
Y:0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a
Z:0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0
X:0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51
Y:0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a
Z:0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0

所以我花了一些时间来了解bash grep,sed等。由于我完全不是软件的家伙,我设法发挥和过滤出一些文本文件在正确的格式下,我想了解如何操作字符串与一个以上的值和上述例子将真正帮助。先谢了。
我确实尝试了printfecho,当文本文件中的每个字符串都有一个值时,我可以使用它们,例如:如果我使用包含数据数据文件

0xff
0xff
0xff
0xff
0xff
.
.
.
.
.
.
..
0xff

所有工作正常,可以转换为printf功能:这是在另一个线程中找到的:

while read line

do

     printf '%d' $line

done < file

上面的工程伟大的一个十六进制值行:这是否可以调整到与我的例子一起工作,或者有更好的方法?

cbeh67ev

cbeh67ev1#

您可以使用(GNU)Awk及其strtonum函数,该函数将以0x开头的字符串转换为十进制数。

  • ,处拆分,从1列开始:
awk 'BEGIN {FS=OFS=","} {for (i=1;i<=NF;i++) $i=strtonum($i); print}' file.txt
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240
  • ,:处拆分,并从列2开始:
awk 'BEGIN {FS=",|:"; OFS=","} {for (i=2;i<=NF;i++) $i=strtonum($i); print}' file.txt
X,81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y,90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z,240,240,240,240,240,240,240,240,240,240,240,240,240,240
X,81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y,90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z,240,240,240,240,240,240,240,240,240,240,240,240,240,240
X,81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y,90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z,240,240,240,240,240,240,240,240,240,240,240,240,240,240
  • 这样,:也将被转换为,。如果不需要这样做,可以分别打印列12和其余列:
awk 'BEGIN {FS=",|:"} {printf "%s:%s", $1, strtonum($2); for (i=3;i<=NF;i++) printf ",%s", strtonum($i); printf "\n"}' file.txt
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240
h7appiyu

h7appiyu2#

一个广义的awk解-

awk -F'[:,]' -v OFS=, '{for(i=1;i<=NF;i++){if($i~/^0x/){$i=strtonum($i)}}if($1!~/^[0-9]/)sub(",",":");print}' file

保存到一个文件中,运行每个示例集:

$: cat x2d
#! /usr/bin/awk -f
BEGIN{ FS="[:,]"; OFS="," }
{ for ( i=1; i<=NF; i++ ) { if ( $i ~ /^0x/ ) { $i=strtonum($i) } }
  if ( $1 !~ /^[0-9]/ ) sub(",",":");
  print;
}

$: ./x2d withName
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240

$: ./x2d noName
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240

只是为了练习,基本的bash也是如此。

$: cat x2d
#! /bin/bash
while IFS=:, read -ra field
do for f in "${field[@]}"
   do case $f in 0x*) printf %d, $f;; *) printf %s: $f;; esac
   done
   printf $'\n'
done < $1

$: ./x2d withName
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81,
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90,
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240,
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81,
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90,
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240,
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81,
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90,
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240,

$: ./x2d noName
81,81,81,81,81,81,81,81,81,81,81,81,81,81,
90,90,90,90,90,90,90,90,90,90,90,90,90,90,
240,240,240,240,240,240,240,240,240,240,240,240,240,240,
81,81,81,81,81,81,81,81,81,81,81,81,81,81,
90,90,90,90,90,90,90,90,90,90,90,90,90,90,
240,240,240,240,240,240,240,240,240,240,240,240,240,240,
81,81,81,81,81,81,81,81,81,81,81,81,81,81,
90,90,90,90,90,90,90,90,90,90,90,90,90,90,
240,240,240,240,240,240,240,240,240,240,240,240,240,240,

对于这么小的数据集,差异是无关紧要的。
如果输入很大,awk会更快。

ghg1uchk

ghg1uchk3#

我会使用perl。对于您的第一个案例:

$ perl -F, -lane 'print join(",", map(hex, @F))' ex1.txt
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240

第二个,前缀是:

$ perl -F'[:,]' -lane 'print $F[0], ":", join(",", map(hex, @F[1..$#F]))' ex2.txt
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240
u59ebvdq

u59ebvdq4#

一个简单的Bash解决方案是让Bash像往常一样解析整数。对于实施例2:

to_dec() {
  local -r IFS=,:
  local -a line
  local -ai nline
  while read -ra line; do
    nline=("${line[@]:1}")
    printf '%s:%s\n' "${line[0]}" "${nline[*]}"
  done
}

然后to_dec < file给出示例2的预期输出。示例1的to_dec将简单得多,因为在这种情况下不需要辅助数组;只要读一下数字:

to_dec() {
  local -r IFS=,
  local -ai nline
  while read -ra nline; do
    printf '%s\n' "${nline[*]}"
  done
}

至于示例2的数学运算,在注解中要求,在纯Bash中可以创建以行前缀命名的函数,然后在数组上执行它们。无论如何,它不会是“高效的”;它是Bash。(另外,据推测,Bash只有整数除法;为了避免这种情况,可以使用某种定点表示,但这在Bash中太过笨拙了。)

#!/bin/bash

X() { local -n a="$1"; local -i i
      for i in "${!a[@]}"; do ((a[i] /= 2)); done; }
Y() { local -n a="$1"; local -i i
      for i in "${!a[@]}"; do ((a[i] *= 2)); done; }
Z() { local -n a="$1"; local -i i
      for i in "${!a[@]}"; do ((a[i] += 2)); done; }

to_dec() {
  local -r IFS=,:
  local -a line
  local -ai nline
  while read -ra line; do
    nline=("${line[@]:1}")
    "${line[0]}" 'nline'  # transform the array
    printf '%s:%s\n' "${line[0]}" "${nline[*]}"
  done
}

to_dec  # takes the script's default stdin / stdout

为了提高效率和浮点运算,awk可以提供帮助:

#!/usr/bin/awk -f

BEGIN { FS = "[:,]" }

function X(numbers) { for (i in numbers) numbers[i] /= 2 }
function Y(numbers) { for (i in numbers) numbers[i] *= 2 }
function Z(numbers) { for (i in numbers) numbers[i] += 2 }

{
  for (i = 2; i <= NF; ++i) numbers[i] = strtonum($i)
  f = $1
  @f(numbers)
  output = $1 ":" numbers[2]
  for (i = 3; i <= NF; ++i) output = output "," numbers[i]
  print output
}

对于大型数据处理,使用更低级的编程语言进行适当的实现会更有效。

vktxenjb

vktxenjb5#

GNU AWK

awk -F'[,:]' -v OFS=, '
    /:/{ withName=1 }
    {
        for(i=1;i<=NF;i++) $i=(strtonum($i) ? strtonum($i) : $i)
    }
    withName{
        sub(/,/,":")
        withName=0
    }1
' file1 file2

81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240
6qftjkof

6qftjkof6#

echo 
'0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51
 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a
 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0
 0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51
 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a
 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0
 0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51
 0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a
 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0' |
gawk -nb '$_ += ORS = RT' RS='\n|,'
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240
81,81,81,81,81,81,81,81,81,81,81,81,81,81
90,90,90,90,90,90,90,90,90,90,90,90,90,90
240,240,240,240,240,240,240,240,240,240,240,240,240,240
gawk -nMb '$++NF = +$_' OFS='\f'
0x5151515151515151515151515151
                              1649317825652239364356745892811089
0x5a5a5a5a5a5a5a5a5a5a5a5a5a5a
                              1832575361835821515951939880901210
0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0
                              4886867631562190709205173015736560
0x5151515151515151515151515151
                              1649317825652239364356745892811089
0x5a5a5a5a5a5a5a5a5a5a5a5a5a5a
                              1832575361835821515951939880901210
0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0
                              4886867631562190709205173015736560
0x5151515151515151515151515151
                              1649317825652239364356745892811089
0x5a5a5a5a5a5a5a5a5a5a5a5a5a5a
                              1832575361835821515951939880901210
0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0
                              4886867631562190709205173015736560
echo '
X:0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51
Y:0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a 
Z:0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0 
X:0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51 
Y:0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a 
Z:0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0 
X:0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51 
Y:0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a 
Z:0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0' |
gawk -nb 'NF == +(ORS = RT) || $_ += _' RS='\n?[A-Z]:|[\n,]'
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240
X:81,81,81,81,81,81,81,81,81,81,81,81,81,81
Y:90,90,90,90,90,90,90,90,90,90,90,90,90,90
Z:240,240,240,240,240,240,240,240,240,240,240,240,240,240

相关问题