Reputation: 2059
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
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
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
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