我在努力寻找一个模式。
我有一个文件,我在文件上搜索一个模式.
xxd -g 2 -c 32 -u file | grep "0045 5804 0001 0000"这将返回包含该模式的行:
FFFF FFFF FFFF 4556 4E54 0000 0116 0100 08B9 0045 5804 0001 0000 2008 0000 0001但我希望它返回该模式之前的4位数字,在本例中是08B9。我怎么能做到呢?
发布于 2022-07-31 22:14:49
不要使用grep,使用sed,例如使用任何sed:
$ xxd whataver | sed -n 's/.*\(....\) 0045 5804 0001 0000.*/\1/p'
08B9发布于 2022-07-31 22:25:53
一种不太优雅但直观地简单的方法可能是将您的grep结果输送到sed中,并使用一个简单的regex将您的搜索词替换为一行末尾的空字符串。这使您想要的块成为结果的最后一个空格分隔的“word”,可以通过管道进入awk并打印最后一个字段(显示在单独行上的步骤,加入它们):
xxd -g 2 -c 32 -u file |
grep "0045 5804 0001 0000" |
sed 's/0045 5804 0001 0000.*//' |
awk '{print $NF}'发布于 2022-07-31 22:58:58
我的xxd打印一个8位地址、一个:、16x4位十六进制代码(用空格分隔),最后打印文件中的原始数据,例如:
$ 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种不同的场景:
xxd输出的最开始,在这种情况下,不存在4位数字的十六进制代码。一组精心设计的xxd输出,用于演示所有4x场景:
$ 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的一个想法
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 --内存不足-错误)。
这就产生了:
Match #1: NA (at front of file)
Match #2: 736A
Match #3: 4220
Match #4: 7364https://stackoverflow.com/questions/73187215
复制相似问题