如何到位printf多行输出?

How to printf multiline output in place?

如果可能的话,我想就地打印多行输出。我有一个像这样的简单 for 循环:

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

我想得到输出:

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

并在同步文件时替换为新尺寸。 但我得到的是:

/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

只跳回一行替换上一行,只有两行输出的时候继续加一行。当输出 3 行时,它会添加额外的 2 行,如下所示:

/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

以此类推
我试过 \r\r 但没有成功。有什么建议吗?

这类事情有不同的终端命令序列。您可能能够保存光标位置并使用以下方法恢复它:

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

对于你的情况,变成:

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

请注意,使用 ALL_CAPS 作为变量名是一种不好的做法,而且此处的变量完全没有必要(除非您希望保留数据以供稍后在脚本中使用)。你可以轻松做到:

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