我试图从一个二进制文件复制一个块到一个新的文件。 我有我想抓取的块的字节偏移量和长度。
我已经尝试使用dd
工具,但这似乎读取和丢弃数据的偏移量,而不是只是寻求(我猜是因为dd是为了复制/转换数据块)。 这使得它非常慢(偏移越高,速度越慢)。这是我试过的命令:
dd if=inputfile ibs=1 skip=$offset count=$datalength of=outputfile
我想我可以写一个小的perl / python /任何脚本来打开文件,寻找偏移量,然后读取和写入所需数量的数据块。
有没有支持这样的东西的实用程序?
是的,今天用dd来做这件事很尴尬。 我们正在考虑在coreutils中将skip_bytes和count_bytes参数添加到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"
您可以使用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。
感谢其他答案。 不幸的是,我不能安装额外的软件,所以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
根据FreeBSD上的man
dd
:
skip=
n在复制之前从输入的开头跳过n个块。 在支持搜索的输入上,使用lseek(2)操作。 否则,输入数据被读取并丢弃。 对于管道,将读取正确的字节数。 对于所有其他设备,读取正确数量的块,而不区分正在读取的部分块或完整块。
使用dtruss
我验证了它确实在Mac OS X上的输入文件上使用了lseek()
。如果你认为速度很慢,那么我同意这是由于1字节的块大小造成的。
你可以使用
--input-position=POS
ddrescue的选项。
你可以试试hexdump命令:
hexdump -v <File Path> -c -n <No of bytes to read> -s <Start Offset> | awk '{$1=""; print $0}' | sed 's/ //g'
例如)从偏移量100开始,从“mycorefile”中读取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 #