Pure Bash, no external utilities
This demonstration does full justification, but you can just omit subtracting the length of the second string if you want ragged-right lines.
pad=$(printf '%0.1s' "-"{1..60})
padlength=40
string2='bbbbbbb'
for string1 in a aa aaaa aaaaaaaa
do
printf '%s' "$string1"
printf '%*.*s' 0 $((padlength - ${#string1} - ${#string2} )) "$pad"
printf '%s\n' "$string2"
string2=${string2:1}
done
Unfortunately, with that technique, the length of the pad string has to be hardcoded to be longer than the longest one you think you'll need, but the padlength
can be a variable as shown. However, you can replace the first line with these three to be able to use a variable for the length of the pad:
padlimit=60
pad=$(printf '%*s' "$padlimit")
pad=${pad// /-}
So the pad (padlimit
and padlength
) could be based on terminal width ($COLUMNS
) or computed from the length of the longest data string.
Output:
a--------------------------------bbbbbbb
aa--------------------------------bbbbbb
aaaa-------------------------------bbbbb
aaaaaaaa----------------------------bbbb
Without subtracting the length of the second string:
a---------------------------------------bbbbbbb
aa--------------------------------------bbbbbb
aaaa------------------------------------bbbbb
aaaaaaaa--------------------------------bbbb
The first line could instead be the equivalent (similar to sprintf
):
printf -v pad '%0.1s' "-"{1..60}
Or similarly for the more dynamic technique:
printf -v pad '%*s' "$padlimit"
Or this (which allows multi-character "ellipses" without having to modify the format string to accommodate the number of characters - .1
in the example above). It assumes that variables with names such as $_1
, $_2
, etc., are unset or empty.:
printf -v pad '%s' "<>"$_{1..60}
You can do the printing all on one line if you prefer:
printf '%s%*.*s%s\n' "$string1" 0 $((padlength - ${#string1} - ${#string2} )) "$pad" "$string2"