1

is it possible to substitute bytes from a binary file myfile from one specific position to another with dd in a loop or is it more comfortable using another command?

The idea is to replace a block B at position position2 with block A at position1 in a loop.

PSEUDO CODE

  @ l = 0

  while (l <= bytelength of myfile)
      copy myfile (from position1 to A+position1)  myfile from (position2 to B+position2)
      @ position1 = position1+steplength
      @ position2 = position2+steplength
      @ l = l+steplength

  end
MichaelScott
  • 387
  • 1
  • 3
  • 21
  • While possible, I would not use a shell command language for this type of file manipulation. Use a language with better support for this type of file I/O. In either case, are you overwriting the bytes at `position2`, or just rearranging the order of bytes within the file? – chepner Mar 12 '13 at 14:31
  • I want to overwrite them if possible... – MichaelScott Mar 12 '13 at 14:47
  • possible duplicate of [How to overwrite some bytes of a binary file with dd?](http://stackoverflow.com/questions/7290816/how-to-overwrite-some-bytes-of-a-binary-file-with-dd) – user2284570 Jan 07 '14 at 22:50

1 Answers1

0

The following lines of code in a text file will do approximately what (I think) you are asking for: copy a file from one location to another, but replace a block of bytes at one location with a block from another location; it uses dd as requested. However, it does create a separate output file - this is necessary to ensure there is no conflict regardless of whether the "input" block occurs before, or after, the "replacement" block. Note that it will do nothing if the distance between A and B is less than the size of the block being replaced - this would result in overlap, and it's not clear if you would want the bytes in the overlapping area to be "the end of A" or "the start of the copy of A".

Save this in a file called blockcpy.sh, and change permissions to include execute (e.g. chmod 755 blockcpy.sh). Run it with

./blockcpy.sh inputFile outputFile from to length

Note that the "from" and "to" offsets have base zero: so if you want to copy bytes starting at the start of the file, the from argument is 0

Here is the file content:

#!/bin/bash
# blockcpy file1 file2 from to length
# copy contents of file1 to file2
# replacing a block of bytes at "to" with block at "from"
# length of replaced block is "length"
blockdif=$(($3 - $4))
absdif=${blockdif#-}
#echo 'block dif: ' $blockdif '; abs dif: ' $absdif
if [ $absdif -ge $5 ]
  then
    # copy bytes up to "to":
    dd if=$1 of=$2 bs=$4 count=1 status=noxfer 2>0
    # copy "length" bytes from "from":
    dd bs=1 if=$1 skip=$3 count=$5 status=noxfer 2>0 >> $2
    # copy the rest of the file:
    rest=$((`cat $1 | wc -c` - $4 - $5))
    skip=$(($4 + $5))
    dd bs=1 if=$1 skip=$skip count=$rest status=noxfer 2>0 >> $2
    echo 'file "'$2'" created successfully!'
  else
    echo 'blocks A and B overlap!'
fi

The 2>0 " 'nix magic" suppresses output from stderr which otherwise shows up in the output (of the type: "16+0 records in").

Floris
  • 45,857
  • 6
  • 70
  • 122