我正在尝试将一个块从一个二进制文件复制到一个新文件中。我有字节偏移和我想要抓取的块的长度。
我尝试使用dd
实用程序,但这似乎是读取并丢弃数据到偏移量,而不仅仅是寻找(我猜因为dd用于复制/转换数据块)。这使得它非常慢(偏移越高越慢。这是我尝试的命令:
dd if=inputfile ibs=1 skip=$offset count=$datalength of=outputfile
我想我可以编写一个小的perl / python /无论什么脚本来打开文件,寻找偏移量,然后以块的形式读取和写入所需数量的数据。
是否有支持此类内容的实用程序?
答案 0 :(得分:13)
您可以使用tail -c+N
修剪输入中的前N个字节,然后您可以使用head -cM
仅输出其输入中的前M个字节。
$ echo "hello world 1234567890" | tail -c+9 | head -c6
rld 12
所以使用你的变量,它可能是:
tail -c+$offset inputfile | head -c$datalength > outputfile
<小时/> 啊,没看到它必须寻求。将此保留为CW。
答案 1 :(得分:10)
是的,今天用dd做这件事很尴尬。我们正在考虑将core_tiltes和count_bytes参数添加到coreutils中的dd来提供帮助。以下应该可以工作:
#!/bin/sh
bs=100000
infile=$1
skip=$2
length=$3
(
dd bs=1 skip=$skip count=0
dd bs=$bs count=$(($length / $bs))
dd bs=$(($length % $bs)) count=1
) < "$infile"
答案 2 :(得分:1)
感谢其他答案。不幸的是,我无法安装其他软件,所以ddrescue选项已经出来了。头/尾解决方案很有意思(我没有意识到你可以提供+尾部),但扫描数据会使它变得很慢。
我最后编写了一个小python脚本来做我想做的事情。缓冲区大小应该调整为与某些外部缓冲区设置相同,但使用下面的值在我的系统上的性能足够。
#!/usr/local/bin/python
import sys
BUFFER_SIZE = 100000
# Read args
if len(sys.argv) < 4:
print >> sys.stderr, "Usage: %s input_file start_pos length" % (sys.argv[0],)
sys.exit(1)
input_filename = sys.argv[1]
start_pos = int(sys.argv[2])
length = int(sys.argv[3])
# Open file and seek to start pos
input = open(sys.argv[1])
input.seek(start_pos)
# Read and write data in chunks
while length > 0:
# Read data
buffer = input.read(min(BUFFER_SIZE, length))
amount_read = len(buffer)
# Check for EOF
if not amount_read:
print >> sys.stderr, "Reached EOF, exiting..."
sys.exit(1)
# Write data
sys.stdout.write(buffer)
length -= amount_read
答案 3 :(得分:1)
skip=
n在复制前从输入的开头跳过 n 块。 在支持搜索的输入上,使用lseek(2)操作。 否则,读取并丢弃输入数据。对于管道, 读取正确的字节数。对于所有其他设备, 读取正确的块数而不区分 正在读取部分或完整的块。
使用dtruss
我确认它在Mac OS X上的输入文件中使用了lseek()
。
如果您认为它很慢,那么我同意这可能是由于1字节块大小所致。
答案 4 :(得分:0)
答案 5 :(得分:0)
您可以尝试使用hexdump命令:
hexdump -v <File Path> -c -n <No of bytes to read> -s <Start Offset> | awk '{$1=""; print $0}' | sed 's/ //g'
例。)从&#39; mycorefile&#39;中读取100个字节。从抵消100开始。
# hexdump -v -c mycorefile -n 100 -s 100 | awk '{$1=""; print $0}' | sed 's/ //g'
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
\0\0\0\0001\0\0\0005\0\0\0\0020003\0
\0\0\0\0\0\0@\0\0\0\0\0\0\0\0\0
\0\0\0\0\0\0\0\0\0\0\0\0\0 003\0
\0\0\0\0\0020\0\0\0\0\0\0001\0\0\0
006\0\0\0\0020003\0\0\0\0\0\0220c\0
\0\0\0\0
然后,如果需要,使用另一个脚本将输出的所有行连接到单行。
如果您只想查看内容:
# /usr/bin/hexdump -v -C mycorefile -n 100 -s 100
00000064 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000074 00 00 00 00 01 00 00 00 05 00 00 00 00 10 03 00 |................|
00000084 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 |......@.........|
00000094 00 00 00 00 00 00 00 00 00 00 00 00 00 a0 03 00 |................|
000000a4 00 00 00 00 00 10 00 00 00 00 00 00 01 00 00 00 |................|
000000b4 06 00 00 00 00 10 03 00 00 00 00 00 00 90 63 00 |..............c.|
000000c4 00 00 00 00 |....|
000000c8
#