Bear in mind that dd
is a raw interface to the read()
, write()
and lseek()
system call. You can only use it reliably to extract chunks of data off regular files, block devices and some character devices (like /dev/urandom
), that is files for which read(buf, size)
is guaranteed to return size
as long as the end of the file is not reached.
For pipes, sockets and most character devices (like ttys), you have no such guarantee unless you do read()
s of size 1, or use the GNU dd
extension iflag=fullblock
.
So either:
{
gdd < file1 bs=1M iflag=fullblock count=99 skip=1
gdd < file2 bs=1M iflag=fullblock count=10
} > final_output
Or:
M=1048576
{
dd < file1 bs=1 count="$((99*M))" skip="$M"
dd < file2 bs=1 count="$((10*M))"
} > final_output
Or with shells with builtin support for a seek operator like ksh93
:
M=1048576
{
command /opt/ast/bin/head -c "$((99*M))" < file1 <#((M))
command /opt/ast/bin/head -c "$((10*M))" < file2
}
Or zsh
(assuming your head
supports the -c
option here):
zmodload zsh/system &&
{
sysseek 1048576 && head -c 99M &&
head -c 10M < file2
} < file1 > final_output