Linux 中的十六进制数序列检查器?

Linux 中的十六进制数序列检查器?

我有一个十六进制数字列表。我想检查一下它们是否按顺序排列。也就是说,它们应该是连续的数字,按升序排列。换句话说,每一行到下一行的增量应该是 1。

十六进制数示例列表:

85AF
85B0
85B1
85B2
85B3
85B4
85B5
85B6
85B7
85B8
85B9
85BA
85BB
85BC
85BD
85BE
85BF
85C0

事实上,我有超过 500 个号码需要检查。

期望的输出:

All numbers are in sequence
     (or)
Numbers are not in sequence.

这是在 Solaris 上,使用 ksh。

答案1

如果输出是十进制的,awk 可以很容易地做到这一点,但它不能解析十六进制数字(至少标准 awk 不能,某些版本如 GNU awk 可以)。您可以使用bc它来进行转换。这适用于所有 POSIX 系统。

{ echo "ibase=16"; cat input.txt; } | bc |
awk 'NR==1 {origin = $0-1}
     $0!=origin+NR {print "Out-of-sequence number at line", NR; exit(1)}' >&2

答案2

正如另一个答案中所述,在 awk 中执行此操作会很好,但是古老的 awk(可能在 Solaris 中可用)不理解十六进制数字。

一个快速的解决方案是使用wc -l一些 ksh 数学:

#! /bin/ksh

first="0x$(head -n1 infile)"
last="0x$(tail -n1 infile)"
lines=$(wc -l <infile)

if [[ "$(( last - first + 1 - lines ))" -eq 0 ]]; then
    echo "All numbers are in sequence."
else
    echo "Numbers are not in sequence."
fi

答案3

这是一种选择:

while read x; do echo $((16#$x)); done <yourfile | awk 's && $1!=s+1{exit(1)}{s=$1}'

此 shell 命令将产生 1(失败时)和 0(成功时)的退出状态。该命令可以在 if 子句中使用,如下所示,以产生所需的输出:

if  while read x; do echo $((16#$x)); done < yourfile | awk 's && $1!=s+1{exit(1)}{s=$1}'
then echo All numbers are in sequence
else echo Numbers are not in sequence
fi

(请注意,您需要将名称“yourfile”替换为包含十六进制数字序列的文件名。)

您还可以省略 shell 循环并使用 GNUawk的选项-n直接处理十六进制数字:

if  sed 's/^/0x/' <yourfile | awk -n 's && $1+0!=s+1{exit(1)}{s=$1+0}'
then echo All numbers are in sequence
else echo Numbers are not in sequence.
fi

注意:这里使用 sed 来创建十六进制数字的语法预期格式(带有前导0x)。

答案4

如果您想要严格的序列,可以通过生成标准具序列并将其与文件进行比较来轻松完成

[ $(comm --nocheck-order -3 \
     <(sed '/\S/!d' file) \
     <(printf "%X\n" \
          $(seq $((16#$(sed '/./!d;q' file))) \
                $((16#$(tac file|sed '/./!d;q')))))) ] &&
echo 'Numbers are not in sequence' ||
echo 'All numbers are in sequence'

只是为了检查所有数字是否都是十六进制:

sed '/^[[:xdigit:] ]*$/!{
        s/.*/Numbers are not in sequence: &/
        q
                        }
     $! d
     s/.*/All numbers are in sequence/' hexadecimal_number.list
  • /^[[:xdigit:] ]*$/检查行中是否只有十六进制符号和空格(或没有 - 空行)
  • !反向匹配,因此{}只要存在上述以外的其他符号就执行命令
  • s/.*/.../;q s用打印行代替 uit 脚本中的Numbers are not in sequence所有行q
  • $! d如果脚本没有执行上一个(模式匹配)并且如果行不是最后d一行,则它从下一行开始
  • s/.*/.../如果脚本到达最后一行(因此所有行都匹配模式),则通过打印s替换最后一行All numbers are in sequence

相关内容