Reputation: 13840
I want to pad a string in Bash to a certain length with any chosen character (or hexcode).
Suppose I have the string AABB
and want to pad it using X
or (0x00
) to length 10:
AABBXXXXXX
I know how to pad with spaces using printf
. How can I pad with an arbitrary character (or hexcode)?
Upvotes: 10
Views: 10342
Reputation: 479
I was inspired by @Socowi's answer and wanted to improve on it!
pad right:
str=123456
echo $str$(printf -- x%.s $(seq -s ' ' $((10-${#str}))))
# ↑ ↑↑
# padding length
# output: 123456xxxx
pad left:
str=123456
echo $(printf -- x%.s $(seq -s ' ' $((10-${#str}))))$str
# ↑ ↑↑
# padding length
# output: xxxx123456
Upvotes: 2
Reputation: 27205
Use printf
to pad with spaces, then replace the spaces with a symbol of your choice. Some examples:
printf %10s AABB | tr ' ' X
prints XXXXXXAABB
.
printf %-10s AABB | tr ' ' X
prints AABBXXXXXX
.
To insert non-printable symbols instead of X
, you can pass an octal escape sequence to tr
. printf
can convert hexadecimal numbers into octal ones:
printf %10s AABB | tr ' ' \\$(printf %o 0x1f)
prints the bytes 1f 1f 1f 1f 1f 1f 41 41 42 42
(can be confirmed by piping through od -tx1 -An
).
str=AABB
yes "" | head -n $((10-"${#str}")) | tr \\n X
printf %s "$str"
Swap the last two lines to insert padding at the right (like %-10s
). Just like before, you can replace X
with \\$(printf %o 0x1f)
to insert non-printable characters.
Upvotes: 19
Reputation: 140960
Solutions using loops:
str=AABB
while ((${#str} < 10)); do
str+='X'
done
echo $str
str=AABB
for ((i=${#str};i<10;++i)); do
str+='X'
done
echo $str
However you can't add null byte to a string in bash. My bash issues a warning:
bash: warning: command substitution: ignored null byte in input
In that case, we need to operate on files, maybe like this:
echo -n AABB >/tmp/1
while (($(wc -c </tmp/1) < 10)); do
echo -ne '\x00' >> /tmp/1
done
cat /tmp/1 | hexdump -C
00000000 41 41 42 42 00 00 00 00 00 00 |AABB......|
0000000a
Upvotes: 4