我需要连接两个文件中的块:
如果我需要连接整个文件,我可以简单地做
cat file1 file2 > output
但我需要从第一个文件中跳过前 1MB,而我只想要第二个文件中的 10MB。听起来像是一份工作dd
。
dd if=file1 bs=1M count=99 skip=1 of=temp1
dd if=file2 bs=1M count=10 of=temp2
cat temp1 temp2 > final_output
是否有可能一步完成此操作?即,不需要保存中间结果?我可以在 中使用多个输入文件吗dd
?
答案1
dd
也可以写入标准输出。
( dd if=file1 bs=1M count=99 skip=1
dd if=file2 bs=1M count=10 ) > final_output
答案2
我认为您无法在一次dd
调用中轻松读取多个文件,但您可以通过几个步骤附加来构建输出文件:
dd if=file1 bs=1M count=99 skip=1 of=final_output
dd if=file2 bs=1M count=10 of=final_output oflag=append conv=notrunc
您需要同时指定conv=notrunc
和oflag=append
。第一个避免截断输出,第二个从现有文件的末尾开始写入。
答案3
请记住,这是,和系统调用dd
的原始接口。您只能可靠地使用它从常规文件、块设备和某些字符设备(例如)中提取数据块,即只要未到达文件末尾就保证返回的文件。read()
write()
lseek()
/dev/urandom
read(buf, size)
size
read()
对于管道、套接字和大多数字符设备(如 tty),除非您执行大小为 1 的 s 或使用 GNUdd
扩展,否则您没有这样的保证iflag=fullblock
。
所以要么:
{
gdd < file1 bs=1M iflag=fullblock count=99 skip=1
gdd < file2 bs=1M iflag=fullblock count=10
} > final_output
或者:
M=1048576
{
dd < file1 bs=1 count="$((99*M))" skip="$M"
dd < file2 bs=1 count="$((10*M))"
} > final_output
或者使用内置支持搜索运算符的 shell,例如ksh93
:
M=1048576
{
command /opt/ast/bin/head -c "$((99*M))" < file1 <#((M))
command /opt/ast/bin/head -c "$((10*M))" < file2
}
或者zsh
(假设您head
支持-c
此处的选项):
zmodload zsh/system &&
{
sysseek 1048576 && head -c 99M &&
head -c 10M < file2
} < file1 > final_output
答案4
与一个巴什主义,以及功能上“无用的使用猫",但最接近OP使用的语法:
cat <(dd if=file1 bs=1M count=99 skip=1) \
<(dd if=file2 bs=1M count=10) \
> final_output
(话虽这么说,斯蒂芬·基特的回答似乎是最高效的可能的方法。)