首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取十六进制模式搜索的前4位数字

获取十六进制模式搜索的前4位数字
EN

Stack Overflow用户
提问于 2022-07-31 22:03:34
回答 6查看 96关注 0票数 -1

我在努力寻找一个模式。

我有一个文件,我在文件上搜索一个模式.

代码语言:javascript
复制
xxd -g 2 -c 32 -u file | grep "0045 5804 0001 0000"

这将返回包含该模式的行:

代码语言:javascript
复制
FFFF FFFF FFFF 4556 4E54 0000 0116 0100 08B9 0045 5804 0001 0000 2008 0000 0001

但我希望它返回该模式之前的4位数字,在本例中是08B9。我怎么能做到呢?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2022-07-31 22:14:49

不要使用grep,使用sed,例如使用任何sed:

代码语言:javascript
复制
$ xxd whataver | sed -n 's/.*\(....\) 0045 5804 0001 0000.*/\1/p'
08B9
票数 1
EN

Stack Overflow用户

发布于 2022-07-31 22:25:53

一种不太优雅但直观地简单的方法可能是将您的grep结果输送到sed中,并使用一个简单的regex将您的搜索词替换为一行末尾的空字符串。这使您想要的块成为结果的最后一个空格分隔的“word”,可以通过管道进入awk并打印最后一个字段(显示在单独行上的步骤,加入它们):

代码语言:javascript
复制
xxd -g 2 -c 32 -u file | 
grep "0045 5804 0001 0000" | 
sed 's/0045 5804 0001 0000.*//' | 
awk '{print $NF}'
票数 0
EN

Stack Overflow用户

发布于 2022-07-31 22:58:58

我的xxd打印一个8位地址、一个:、16x4位十六进制代码(用空格分隔),最后打印文件中的原始数据,例如:

代码语言:javascript
复制
$ xxd -g 2 -c 32 -u  file
         1         2         3         4         5         6         7         8         9         10        11        12        13
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
00000000: 4120 302E 3730 3220 6173 646C 666B 6A61 7364 666C 6B61 6A73 6466 3B6C 6B61 736A  A 0.702 asdlfkjasdflkajsdf;lkasj
00000020: 6466 6C6B 6173 6A64 660A 4220 302E 3836 3820 6173 646C 666B 6A61 7364 666C 6B61  dflkasjdf.B 0.868 asdlfkjasdflka
00000040: 322E 3135 3220 6173 646C 666B 6A61 7364 666C 6B61 6A73 6466 3B6C 6B61 736A 6466  2.152 asdlfkjasdflkajsdf;lkasjdf
00000060: 6C6B 6173 6A64 660A                                                              lkasjdf.

注释:添加的前两行(标尺)以显示列编号

OP似乎只对4位十六进制代码感兴趣,这意味着我们对列11-89 (包括)中的数据感兴趣。

从这里开始,我们需要解决4种不同的场景:

  1. 匹配可能发生在xxd输出的最开始,在这种情况下,不存在4位数字的十六进制代码。
  2. 匹配发生在行的开头,因此我们对前一行末尾的4位十六进制代码感兴趣。
  3. 匹配发生在行的中间,在这种情况下,我们对匹配之前的4位十六进制代码感兴趣。
  4. match跨越两行,在这种情况下,我们对第一行比赛之前的4位十六进制代码感兴趣

一组精心设计的xxd输出,用于演示所有4x场景:

代码语言:javascript
复制
$ cat xxd.out 
00000000: 0045 5804 0001 0000 6173 646C 666B 6A61 7364 666C 6B61 6A73 6466 3B6C 6B61 736A  A 0.702 asdlfkjasdflkajsdf;lkasj
#         ^^^^^^^^^^^^^^^^^^^
00000020: 0045 5804 0001 0000 660A 4220 0045 5804 0001 0000 646C 666B 6A61 7364 0045 5804  dflkasjdf.B 0.868 asdlfkjasdflka
#         ^^^^^^^^^^^^^^^^^^^           ^^^^^^^^^^^^^^^^^^^                     ^^^^^^^^^
00000040: 0001 0000 3B6C 6B61 736A 6466 6C6B 6173 6A64 660A 4320 332E 3436 3720 6173 646C  jsdf;lkasjdflkasjdf.C 3.467 asdl
#         ^^^^^^^^^

注释:添加注释以突出显示我们的匹配

使用awk的一个想法

代码语言:javascript
复制
x='0045 5804 0001 0000'

cat xxd.out |                                             # simulate feeding xxd output to awk
awk -v x="${x}" '

function parse_string() {

    while ( length(string) > (2 * lenx) ) {
          pos= index(string,x)

          if (pos) {
             if   (pos==1) output= "NA (at front of file)"
             else          output= substr(string,pos - 5,4)

             cnt++    
             printf "Match #%s: %s\n", cnt, output
             string= substr(string,pos + lenx)
          }
          else {
             string= substr(string,length(string) - (2 * lenx))
             break
          }
    }
}

BEGIN { lenx = length(x) }

      { string=string substr($0,11,80)                   # strip off address & raw data, append 4-digit hex codes into one long string
        if ( length(string) > (1000 * lenx) )
           parse_string()
      }

END   { parse_string() }
'

注意: parse_string()函数和各种if (length(string) > ...)测试允许我们将内存使用量限制在搜索模式长度的1000倍(在本例中是=> 1000 x 19 = 19,000);当然,在小文件的情况下,它允许我们处理大型(R)文件,而不必担心占用内存(或者在最坏的情况下是OOM --内存不足-错误)。

这就产生了:

代码语言:javascript
复制
Match #1: NA (at front of file)
Match #2: 736A
Match #3: 4220
Match #4: 7364
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73187215

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档