42

I have a 1TB big file (disk-image from a damaged drive) and a 1.3MB small file (beginning of a disk-file).

Using the contents of the small file, I want to overwrite portions of the big file. That is, I want to insert/overwrite the first 1.3MB of the 1TB-image using the small file.

Using small temporary files for testing I was unable to overwrite parts of the files. Rather, dd overwrote the files completely. This is not what I want.

Is dd able to do this?

bos
  • 887
  • 3
    In addition to the very good answers below, you can use the seek=nn and skip=nn parameters to set the starting points in your files, and count=nn to copy less than the whole input file. – Guntram Blohm Jul 28 '14 at 09:29

4 Answers4

49

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# 
Lawrence
  • 2,302
  • 18
    And it wasn't part of the original question, but you can write to somewhere other than the beginning of the output file using the seek option, and start reading somewhere other than the beginning of the input file using the skip option. Together with the other options, you can copy an arbitrary part of one file to an arbitrary position in another. – hobbs Jul 28 '14 at 19:58
28

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.

Michael Homer
  • 76,565
7

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
  • 2
    but without all the problems and limitations of dd what problems and limitations? – stu Jul 30 '18 at 14:02
5

Example:

printf '\xa1' | dd conv=notrunc of=Yourfile bs=1 seek=$((0xoffset))
sam
  • 22,765
craken
  • 181