我有一个 2GB 的原始格式文件。我想搜索特定十六进制值"355A3C2F74696D653E"的所有外观,并收集以下 28 个字符。
示例:355A3C2F74696D653E323031312D30342D32365431343A34373A30322D31343A34373A3135
在这种情况下,我想要输出:"323031312D30342D32365431343A34373A30322D31343A34373A3135"
或更好:2011-04-26T14:47:02-14:47:15
我试过
xxd -u InputFile | grep '355A3C2F74696D653E' | cut -c 1-28 > OutputFile.txt
和
xxd -u -ps -c 4000000 InputFile | grep '355A3C2F74696D653E' | cut -b 1-28 > OutputFile.txt
但我无法让它工作。
谁能给我一个提示?
当您使用xxd
在我看来,您想像搜索二进制数据一样搜索文件。我建议为此使用更强大的编程语言;Unix shell 工具假设有行尾,并且文本主要是 7 位 ASCII。考虑使用 Python:
#!/usr/bin/python
import mmap
fd = open("file_to_search", "rb")
needle = "x35x5Ax3Cx2Fx74x69x6Dx65x3E"
haystack = mmap.mmap(fd.fileno(), length = 0, access = mmap.ACCESS_READ)
i = haystack.find(needle)
while i >= 0:
i += len(needle)
print (haystack[i : i + 28])
i = haystack.find(needle, i)
如果你的 grep 支持-P
参数,那么你可以简单地使用以下命令。
$ echo '355A3C2F74696D653E323031312D30342D32365431343A34373A30322D31343A34373A3135' | grep -oP '355A3C2F74696D653EK.{28}'
323031312D30342D32365431343A
对于 56 个字符,
$ echo '355A3C2F74696D653E323031312D30342D32365431343A34373A30322D31343A34373A3135' | grep -oP '355A3C2F74696D653EK.{56}'
323031312D30342D32365431343A34373A30322D31343A34373A3135
为什么要先转换为十六进制? 看看这个 awk 脚本是否适合您。 它查找要匹配的字符串,然后打印接下来的 28 个字符。 特殊字符使用模式中的反斜杠进行转义。
改编自这篇文章:比赛前后的格雷普角色?
为了便于阅读,我添加了一些空白行。
VirtualBox:~$ cat data.dat
Thisis a test of somerandom characters before thestringI want5Z</time>2011-04-26T14:47:02-14:47:15plus somemoredata
VirtualBox:~$ cat test.sh
awk '/5Z</time>/ {
match($0, /5Z</time>/); print substr($0, RSTART + 9, 28);
}' data.dat
VirtualBox:~$ ./test.sh
2011-04-26T14:47:02-14:47:15
VirtualBox:~$
编辑:我刚刚意识到一些事情。 正则表达式需要调整为非贪婪等,并且在需要调整正则表达式和 awk 之间,以根据需要处理多次出现。 也许一些更了解awk的人可以提出改进,因为我真的很生疏。无论如何都要考虑的方法。