我有一个输入文件,它总是 520 字节的倍数。即
Input file 1- 1040 bytes
Input file 2- 5200 bytes
我需要从输入文件中复制每 512 个字节,并跳过输入文件中的接下来 8 个字节到输出文件,即
Output file data = Copy first 512 bytes of input file - Skip 8 bytes - Copy second 512 bytes of input file- Skip 8 bytes --.
。
因此,我的输出文件应该始终是 512 字节的倍数
Input file 1- 1040 bytes Output file 1 - 1024 bytes
Input file 2- 5200 bytes Output file 2 - 5120 bytes
我需要在 shell 脚本中执行此操作,请提供任何帮助。
答案1
正确的工具
bbe
是“一个sed
类似于 的二进制文件编辑器”。在 Debian 中,它位于名为 的包中bbe
。您可以按如下方式完成所需操作:
<"Input file 1" bbe -b :520 -e 'd 512 *' >"Output file 1"
bbe
是正确的工具。如果你能用就用。下面的脚本是为了以防你不能使用bbe
。
可移植脚本
虽然不是最快的代码,但它是这样的:
#!/bin/sh
useful=512
useless=8
while :; do
dd bs=1 count="$useful" 2>/dev/null
[ "$(dd bs=1 count="$useless" 2>/dev/null | wc -c)" -lt "$useless" ] && exit
done
将代码保存为my_filter
,然后调用:
<"Input file 1" ./my_filter >"Output file 1"
笔记:
- 我认为该代码是可移植的。
bbe
速度更快(尽管对于 5200 字节或更少的文件,您可能不会注意到差异)。- 它似乎
bs="$useful" count=1
应该更好,但前提是你dd
支持iflag=fullblock
(也可能不支持)并且你使用它。阅读从文件中读取精确字节数的 POSIX 方法是什么? dd
当第二个读取的内容少于应有的内容时,代码将退出。这样就可以检测到 EOF。对于您的文件(“始终是 520 字节的倍数”),第一个文件dd
在第二个文件读取之前会少于应有的内容,但dd
以可移植的方式使用第一个文件检测这种情况同时仍保存输出并不像使用第二个文件那样简单,因为wc -c
第二个文件dd
的输出无论如何都应该被丢弃。- 由于脚本检测 EOF 的方式,如果发生 EOF(即如果 EOF 发生在中间),它不会丢弃部分有用块。但对于您的文件(“始终是 520 字节的倍数”),这种情况永远不会发生。对于任意大小的文件,都可能发生这种情况。请注意,
bbe
即使在这些情况下,提供的命令也会生成与脚本相同的输出。 - 要定制脚本并使用 512 和 8 以外的值,只需修改
useful=512
和useless=8
行即可。 - 由于脚本检测 EOF 的方式,如果您设置,它将永远不会退出
useless=0
(这个边缘情况可以通过 轻松解决cp "Input file 1" "Output file 1"
)。 dd
支持skip=
。使用它来跳过$useless
字节似乎很优雅,但检测 EOF 会变得很复杂。- 您可以轻松修改代码以从位置参数中获取
useful
和。扩展为第一个位置参数的值,扩展为第二个位置参数的值。因此,您可以分别使用和来代替和。然后您需要运行来代替。这将允许您在运行时传递任意值。useless
$1
$2
useful=512
useless=8
useful="$1"
useless="$2"
./my_filter
./my_filter 512 8