2

I've a big file from which i want to remove some content, the file is binary, and i don't have line numbers, but hex address, so how can i remove the region between:
0x13e70a00 and 0x1eaec03ff
With sed (both inclusive)

Will something like this, work?

sed -n 's/\x13e70a00/,s/\x1eaec03ff/ p' orig-data-file > new-file
doterobcn
  • 307
  • 1
  • 4
  • 15
  • possible duplicate of [How to dump part of binary file](http://stackoverflow.com/questions/9451890/how-to-dump-part-of-binary-file) – Sebastian Jul 30 '13 at 00:01
  • @Sebastian i couldn't found that one, but as far as i know, that one is about getting the content somewhere else, and what i want is to remove it from the file (and get a file without that region) – doterobcn Jul 30 '13 at 00:16

2 Answers2

3

from what you wrote it looks like you are trying to delete all the bytes between the two hex patterns. for that you will need

this deletes all the bytes between the patterns inclusive of the patterns.

 sed 's/\x13\xe7\x0a\x00.*\x1e\xae\xc0\x3f//g' in >out

This deletes all bytes between patterns leaving the patterns intact. (there is a way to this with numbered parts of regexes but this is a bit clearer to beging with)

 sed 's/\x13\xe7\x0a\x00.*\x1e\xae\xc0\x3f/\x13\xe7\x0a\x00\x1e\xae\xc0\x3f/g' in >out

They search s/ for a <pattern1> followed by any text .* followed by <pattern2> and replace it with either nothing //g or just the two edges /<pattern1><pattern2>/g throughout the file /g

If you want to delete (or replace) from byte 300 to byte 310:

sed 's/\(.\{300\}\).\{10\}/\1rep-str/' in>out

this matches the first 300 characters (.\{300\} )and remembers them (the \(\) ). It matches the next 10 characters too. It replaces this whole combined match with the first 300 characters (\1) followed by your replacement string rep-str this replacement string can be empty to just delete the text between bytes 300 and 310.

However, this is quite brittle if there are any newline characters. if you can live without replacement:

dd if=file bs=1 skip=310|dd of=file bs=1 seek=300 conv=notrunc

this does an in place replacement by copying from the 310th byte onwards till into the file starting from 300 position thus deleting 10 bytes

an even more general alternative is

dd if=in bs=1 count=300>out
printf "replacement text">>out
dd if=in bs=1 skip=310>>out

though the simplest thing to do will be to use a hex editor like Bless

staticd
  • 1,194
  • 9
  • 13
2

You should be able to use a clever combination of converting bash numbers from hex to decimal, bash math to add 1 to the decimal offsets, and cut --complement -b to remove the correct segment from the file.

EDIT: Like this:

$ snip_out 0x0f 0x10 <<< "0123456789abcdeffedcba9876543210" | od -t x1
0000000 30 31 32 33 34 35 36 37 38 39 61 62 63 64 65 65
0000020 64 63 62 61 39 38 37 36 35 34 33 32 31 30
0000036

Where snip_out is a two-parameter shell-script that operates on stdin and stdout:

#!/bin/bash

START_RANGE_DEC=$(printf "%d" $1)
END_RANGE_DEC=$(printf "%d" $2)

# Most hex ranges begin with 0; cut begins with 1.
CUT_START_DEC=$(( $START_RANGE_DEC + 1 ))
CUT_END_DEC=$(( $END_RANGE_DEC + 1 ))

# cut likes to append a newline after output. Use head to remove it.
exec cut --complement -b $CUT_START_DEC-$CUT_END_DEC | head -c -1
Community
  • 1
  • 1
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
  • 1
    @downvoter: I'd appreciate a comment to help me improve this and other posts. – Jeff Bowman Jul 30 '13 at 04:13
  • thanks, i'll check this right away, however the file is very big (55GB) so it might take a while. also i found that with dd i could be able to extract n bytes from my file, knowing as i do the positions, i should be able to calculate the bytes i need....i will also try that! – doterobcn Jul 30 '13 at 09:46