You are not logged in.

#1 Today 14:00:03

Bedna
Member
Registered: 2025-11-14
Posts: 51
Website

printf with alignment

I'm trying to create a "border" around an lsblk output in a bash script.

I have following code, but printf is not creating the rightmost # as I interpret it should.

COLS=60
BREAK="$(printf "%${COLS}s" | tr ' ' '#')"
mapfile -t lsblk_output < <(lsblk)
echo "$BREAK"
for line in "${lsblk_output[@]}"; do
  printf "# %-${COLS}s%s\n" "$line" '#'
done
echo "$BREAK"

The output becomes this:

############################################################
# NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS           #
# sda           8:0    0 465,8G  0 disk                       #
# ├─sda1        8:1    0   384M  0 part                   #
# ├─sda2        8:2    0    38G  0 part                   #
# ├─sda3        8:3    0   128G  0 part                   #
# └─sda4        8:4    0 299,4G  0 part                   #
# sdb           8:16   0 167,7G  0 disk                       #
# └─sdb1        8:17   0 167,7G  0 part [SWAP]            #
# sdc           8:32   0   2,7T  0 disk                       #
# └─sdc1        8:33   0   2,7T  0 part /media/fil-fitt   #
# nvme0n1     259:0    0   1,8T  0 disk                       #
# └─nvme0n1p1 259:1    0   1,8T  0 part /media/games      #
# nvme1n1     259:2    0 931,5G  0 disk                       #
# ├─nvme1n1p1 259:3    0     1G  0 part /boot/efi         #
# ├─nvme1n1p2 259:4    0  99,5G  0 part /var/cache        #
# │                                     /var/log            #
# │                                     /                   #
# ├─nvme1n1p3 259:5    0   783G  0 part /home             #
# └─nvme1n1p4 259:6    0    48G  0 part [SWAP]            #
############################################################

It doesn't make sense to me. The -60 is from the left border right? Not after the "# ", if it starts after the initial "# ", it should be "printf "# %-$(( COLS - 2 ))s%s\n" "$line" '#'", but that doesn't align with anything either. Besides, the main problem is the rightmost # is not consistent, and I can't figure out what is making it shift randomly.
What am I doing wrong?

I could use tput, catch current cursor location and yadayada, but in my mind, printf should be able to do this right?
I have also tried counting characters or bytes in $line within the for loop and use that for alignment, but wc seems to count all the spaces as one byte (or something) so I can't get correct alignment with that either.

Thank you in advance.

Last edited by Bedna (Today 14:09:34)

Offline

#2 Today 14:20:41

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 78,704

Re: printf with alignment

while read line; do printf "# %-60s%s\n" "$line" '#'; done < <(lsblk)

Online

#3 Today 14:51:33

Bedna
Member
Registered: 2025-11-14
Posts: 51
Website

Re: printf with alignment

seth wrote:
while read line; do printf "# %-60s%s\n" "$line" '#'; done < <(lsblk)

Gets the exact same result, ie the right is not aligned.

Offline

#4 Today 14:58:40

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 78,704

Re: printf with alignment

Oh, it's bash… zsh does what you expect hmm

Online

Board footer

Powered by FluxBB