Objective: Truncate or remove last n
bytes from a binary (or text) file on Unix / Linux.
Let’s say that we have a binary file called foo.bin
and we need to strip the last 20 bytes from the file. To do that, we can either use the dd
or truncate
utility. truncate
is my preferred choice.
Before we strip the last 20 bytes from the foo.bin
file, we first need to determine the new file size. To do that, we will need to use the stat
command.
1 2 |
$ stat -c '%s' foo.bin 23874470 |
The file size is 23874470
bytes. To minus 20 from the result, we can use the following shell arithmetic expression. This step is required only if you are trying to script the whole process. The newfsize
variable will be assigned with the new file size of 23874450
bytes.
1 2 3 4 |
$ newfsize=$(($(stat -c '%s' foo.bin) - 20)) $ echo $newfsize 23874450 |
If the above expression does not work, use the expr
utility to evaluate the expression.
1 2 3 4 |
$ newfsize=$(expr $(stat -c '%s' foo.bin) - 20) $ echo $newfsize 23874450 |
We can now use the truncate
command to remove the last 20 bytes from the file. Note that by default, truncate
will modify the input file.
1 2 3 4 |
$ truncate -s $newfsize foo.bin $ stat -c '%s' foo.bin 23874450 |
You can also specify -20
as the size to truncate
to reduce the file size by 20 bytes.
1 2 3 4 |
$ truncate -s -20 foo.bin $ stat -c '%s' foo.bin 23874450 |
To truncate a file using dd
, we can use the following command syntax. The output will be written to dd-foo.out
file.
1 2 3 4 |
$ dd if=foo.bin of=dd-foo.out bs=1 count=$newfsize 23874450+0 records in 23874450+0 records out 23874450 bytes (24 MB) copied, 65.5627 s, 364 kB/s |
We have to specify a block size of 1 byte (bs=1
) and set the count
parameter to the new file size. Note that this is going to be very slow as the block size of 1 byte is not optimal for disk IO.