使用bash在包含非ASCII字符的二进制文件中的两个匹配模式之间提取数据

时间:2015-09-21 09:30:52

标签: bash sed pattern-matching hexdump extended-ascii

我正在尝试从二进制文本文件中提取jpeg图像。我想提取0xFF 0xD8(图像开始)和0xFF 0xD9(图像结束)之间的所有数据。之前,我已经成功运行以下命令从一个段落文件中获取所需的image.jpg.txt:

sed 's/.*\xFF\xD8/\xFF\xD8/; s/\xFF\xD9.*/\xFF\xD9/' received.txt > image.jpg

但是当我尝试在不同的文件上运行相同的操作时,它并没有起作用。我也尝试过使用

sed -n '/\xFF\xD8/,/\xFF\xD9/p' received.txt > temp.txt
sed 's/.*\xFF\xD8/\xFF\xD8/; s/\xFF\xD9.*/\xFF\xD9/' temp.txt > image.jpg

删除匹配行之前或之后的任何行,但没有成功。

虽然文件太大,但我粘贴了以下相关部分的十六进制转储:

0a 55 57 5d 50 cf ff d8 ff fe ff ff ff d9 df 47 fe e7 c9 3b e9 9b 6b 55 c4 57 9b 98 73 fd 15 f7 77 7e f7 95 dd 55 f7 55 05 cc 55 97 55 dd 62 d1 1f 51 ef f1 ef fb e9 bf ed 5f bf f2 9d 75 af fe 6b fb bf 8f f7 f7 7e ff d3 bf 8e d5 5f df 57 75 fe 77 7b bf d7 af df 5d fb 0a 47 de d5 ff c1 23 9b 20 08 20 65 3c 06 83 11 05 30 50 a0 20 55 20 84 41 04 c2 59 50 89 64 44 44 10 05 20 87 28 1d a9

在这种情况下,所需输出的十六进制转储是:

ff d8 ff fe ff ff ff d9

更新

在尝试解决问题时,我发现sed命令会删除匹配模式之前或之后的所有字符,直到非ASCII字符(0x80 - 0xFF),但不会超出该非ASCII字符。例如,如果我们尝试:

echo 55 57 5d 50 cf 50 65 7f ff d8 ff fe ff ff ff d9 | xxd -r -p | sed 's/.*\xFF\xD8/\xFF\xD8/' > output

输出的十六进制转储可以看作:

xxd output

是:

55 57 5d 50 cf ff d8 ff fe ff ff ff d9

可以看出,非ASCII字符和匹配模式之间的字符被删除,但非ASCII字符之前的字符不是。

替代解决方案(不完美)

我使用以下命令来解决问题:

sed 's/\xFF\xD8/\x0A\xFF\xD8/; s/\xFF\xD9/\xFF\xD9\x0A/' received.txt > temp.txt

然后运行以下命令(如果在0xFF 0xD8和0xFF 0xD9之间没有新行字符(0x0A),它将起作用):

sed -n '/\xFF\xD8/{/\xFF\xD9/p}' temp.txt > image.jpg

但如果image.jpg文件为空(执行上述命令后),则运行以下命令:

sed -n '/\xFF\xD8/,/\xFF\xD9/p' temp.txt > image.jpg

这些命令将执行所需的工作,除了它将0x0A放在image.jpg文件的末尾(即在0xFF 0xD9之后)。在我的情况下,它没有产生任何问题,因为JPEG文件在0xFF 0xD9标记之后自动丢弃数据。

如果图像文件为空,我就被执行了'当@chaos想出一个完美的解决方案时。所以,我现在正在遵循他的解决方案。非常感谢@chaos!

请按照以下链接查看混沌解决方案! https://unix.stackexchange.com/questions/231289/extract-data-between-two-matched-patterns-in-a-binary-file

备注:

以下是如何从十六进制转储中获取实际数据,您可以将其转换为sed命令:

echo 0a 55 57 5d 50 cf ff d8 ff fe ff ff ff d9 df 47 fe e7 c9 3b e9 9b 6b 55 c4 57 9b 98 73 fd 15 f7 77 7e f7 95 dd 55 f7 55 05 cc 55 97 55 dd 62 d1 1f 51 ef f1 ef fb e9 bf ed 5f bf f2 9d 75 af fe 6b fb bf 8f f7 f7 7e ff d3 bf 8e d5 5f df 57 75 fe 77 7b bf d7 af df 5d fb 0a 47 de d5 ff c1 23 9b 20 08 20 65 3c 06 83 11 05 30 50 a0 20 55 20 84 41 04 c2 59 50 89 64 44 44 10 05 20 87 28 1d a9 | xxd -r -p

您可以通过以下方式查看文件的十六进制转储:

xxd file.txt

0 个答案:

没有答案