Shuzheng
Shuzheng

Reputation: 13840

Pad a string to a certain length with a chosen character (or hexcode) in Bash?

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

Answers (3)

mightbesimon
mightbesimon

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

Socowi
Socowi

Reputation: 27205

For strings without spaces

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).

For strings with spaces

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

KamilCuk
KamilCuk

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

Related Questions