DenisZ
DenisZ

Reputation: 331

How to printf multiline output in place?

I'd like to print multiline output in place if it's posible. I have a simple for loop like this:

for i in {1..100}; do
  OUTP=`df -h |grep sda`
  echo -ne "$OUTP\r"
  sleep 5
done

I would like to get output:

/dev/sda2       110G  9.0G   96G   9% /mnt/sdb
/dev/sda1      1022M  248M  775M  25% /mnt/sdb/boot/efi

and to be replaced with new sizes, as I'm syncing files. but instead I'm getting:

/dev/sda2       110G   19G   87G  18% /mnt/sdb
/dev/sda2       110G   19G   86G  18% /mnt/sdb/boot/efi
/dev/sda2       110G   19G   86G  18% /mnt/sdb/boot/efi
/dev/sda2       110G   19G   86G  19% /mnt/sdb/boot/efi
/dev/sda2       110G   20G   85G  19% /mnt/sdb/boot/efi

It is jumping back only one line and replacing previous line, and keeps adding one line when there is only output of two lines. When output 3 lines it would add extra 2 lines like following:

/dev/sda2       110G   49G   56G  47% /mnt/sdb
/dev/sda1      1022M  248M  775M  25% /mnt/sdb/boot/efi
/dev/sda3       299G  949M  283G   1% /mnt/sdb/var
/dev/sda2       110G   49G   56G  47% /mnt/sdb
/dev/sda1      1022M  248M  775M  25% /mnt/sdb/boot/efi
/dev/sda3       299G  1.5G  282G   1% /mnt/sdb/var
/dev/sda2       110G   49G   56G  47% /mnt/sdb
/dev/sda1      1022M  248M  775M  25% /mnt/sdb/boot/efi
/dev/sda3       299G  1.9G  282G   1% /mnt/sdb/var
/dev/sda2       110G   49G   56G  47% /mnt/sdb
/dev/sda1      1022M  248M  775M  25% /mnt/sdb/boot/efi
/dev/sda3       299G  2.4G  281G   1% /mnt/sdb/var

And so on.
I tried \r\r but no luck. Any suggestions?

Upvotes: 0

Views: 569

Answers (1)

William Pursell
William Pursell

Reputation: 212248

There are different terminal command sequences for that sort of thing. You might be able to save the cursor position and restore it with:

$ tput sc; printf 'multi\nline\noutput\n'; tput rc; printf '%s' 'overwrite line 1'; echo; echo; echo
overwrite line 1
line
output

For your case, that becomes:

tput sc     # Save cursor position
for i in {1..100}; do
  outp=$(df -h |grep sda)
  printf '%s' "$outp"
  tput rc   # Restore cursor position
done

Note that it is bad practice to use ALL_CAPS for variable names, and also that the variable here is totally unnecessary (unless you wish to retain the data for use later in the script). You could easily do:

for i ...; do
  tput sc
  df -h | grep sda
  tput rc
done

Upvotes: 1

Related Questions