Dien Nguyen
Dien Nguyen

Reputation: 2059

padding file to 4 byte boundary

In linux bash, how can we concatenate files with padding on 4-byte boundary. I have 3 files a.txt, b.txt, c.txt, and want to concatenate them to create d.txt, each element file is started on 4-byte boundary.

a.txt: 1 byte
b.txt: 2 bytes
c.txt: 4 bytes

d.txt should be
0-3: a.txt
4-7: b.txt
8-11: c.txt

Any suggestions are appreciated. Thanks and Best Regards, Dien

Upvotes: 3

Views: 2016

Answers (3)

kev
kev

Reputation: 161644

for i in {a..c}.txt
do
    cat $i
    head -c $(((4-$(stat -c %s $i)%4)%4)) /dev/zero
done >d.txt

Upvotes: 1

William Pursell
William Pursell

Reputation: 212238

Assuming you wish to pad with spaces, one relatively simple solution is:

perl -wpE 'BEGIN{ $/ = \4 } print " " x ( 4 - length )
    if length != 4' a.txt b.txt c.txt > d.txt

Upvotes: 3

paxdiablo
paxdiablo

Reputation: 881303

If you need zero-byte padding, you can use head with both the actual files and /dev/zero (to get padding). First set up some test files:

pax> echo -n 1 >a.txt ; echo -n 12 >b.txt ; echo -n 1234 >c.txt

Then the following code will give you what you want.

pax> ( head -c1 a.txt ; head -c3 /dev/zero ;
       head -c2 b.txt ; head -c2 /dev/zero ;
       head -c4 c.txt ) | od -xcb
0000000    0031    0000    3231    0000    3231    3433
          1  \0  \0  \0   1   2  \0  \0   1   2   3   4
        061 000 000 000 061 062 000 000 061 062 063 064
0000014

You can see the padding has been placed in the output stream. So a script to do this is as simple as:

( head -c1 a.txt ; head -c3 /dev/zero )  >d.txt
( head -c2 b.txt ; head -c2 /dev/zero ) >>d.txt
( head -c4 c.txt                      ) >>d.txt

Or, if you don't really care what goes into the padding area, you can use a one-liner like:

cat [abc].txt | sed 's/^\(.\)\(..\)/\1___\2__/' >d.txt

This will produce a file containing:

1___12__1234

Upvotes: 2

Related Questions