Is dd able to overwrite parts of a file?

If you use the conv=notrunc argument, you can replace just the first however many bytes.
e.g. dd conv=notrunc if=small.img of=large.img

root@debian:~/ddtest# dd if=/dev/zero of=file1.img bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 1.14556 s, 9.2 MB/s
root@debian:~/ddtest# dd if=/dev/urandom of=file2.img bs=1M count=1
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.207185 s, 5.1 MB/s
root@debian:~/ddtest# head file1.img 

<< Blank space here as it's all Zeroes >>

root@debian:~/ddtest# dd conv=notrunc if=file2.img of=file1.img 
2048+0 records in
2048+0 records out
1048576 bytes (1.0 MB) copied, 0.00468016 s, 224 MB/s
root@debian:~/ddtest# head file1.img 
^�v�y�ے!� E�91����  << SNIP Random garbage >>
root@debian:~/ddtest# 

If you want to overwrite only at the start of the file, and leave the rest intact, use the conv=notrunc option to prevent truncation:

dd conv=notrunc if=/dev/zero of=test bs=1024 count=1024

notrunc means:

Do not truncate the output file. Preserve blocks in the output file not explicitly written by this invocation of the dd utility.

It is in POSIX and so supported by every version of dd.


If you want to overwrite the start of big-file with the content of small-file without affecting the rest, you can just do with any Bourne-like shell:

cat small-file 1<> big-file

The <> redirection operator opens the file in read+write mode without truncation. That would be equivalent to using dd's conv=notrunc but without all the problems and limitations of dd.

If you want to write the content anywhere else than at the very start of the file, you'd need to seek at the desired position in the file. That's where dd and its seek=xxx comes handy, though you could also use a shell that has builtin seek operators like ksh93 or zsh:

cat small-file 1<> big-file >#((12345)) # ksh93

zmodload zsh/system; {sysseek -u1 12345 && cat small-file} 1<> big-file # zsh

Tags:

Dd