如何在同一行显示和更新回声

Lui*_*ado 99 bash

我在Bash中有以下内容(在Linux中)

for dir in Movies/*
do
  (cd "$dir" && pwd|cut -d \/ -f5|tr -s '\n' ', ' >> ../../movielist &&
  exiftool * -t -s3 -ImageSize -FileType|tr -s '\t' ',' >> ../../movielist )
echo "Movie $movies - $dir ADDED!"
let movies=movies+1
done
Run Code Online (Sandbox Code Playgroud)

但我希望这样做,以便"echo"在下一行显示以下回声(不与最后一个echo输出连接,但替换它),以使它看起来像是在更新.类似于具有百分比的进度条将如何显示在同一行上.

Lui*_*ado 175

好吧,我没有正确阅读此man echo页面.

如果我添加了第3个转义字符,echo有2个选项可以执行此操作.

2个选项是-n-e.

-n不会输出尾随换行符.这样每次我回应一些东西时,我都不会再去新线.

-e 将允许我解释反斜杠转义符号.

猜猜我想用什么逃脱符号:\r.是的,回车会让我回到起点,看起来我会在同一条线上更新.

所以回声线看起来像这样:

echo -ne "Movie $movies - $dir ADDED!"\\r

我不得不逃脱逃脱的象征,所以巴什不会杀死它.这就是你\在那里看到2个符号的原因.

正如威廉所提到的,printf也可以做类似的(甚至更广泛的)这样的任务.

  • 只是未来的一个注释:printf将完全相同的事情,没有任何选择.printf的优点通常在每个环境和操作系统中表现相似,而echo有时表现得非常不同.对于跨平台脚本(或者如果您认为您可能会关心它),使用printf是最佳实践. (10认同)
  • `printf a; printf b`输出`ab` ---`printf a \\ r; printf b`输出`b` ---`printf a \\ r; 睡1; printf b`输出`a`,然后输出`b` (6认同)
  • 引用的简单修复是将“\r”也放在双引号内。但一般来说,就像其他人已经评论的那样,避免使用“echo -e”而使用“printf”。 (2认同)

aru*_*aku 59

如果我理解得很好,你可以用以下代码取代你的回声:

echo -ne "Movie $movies - $dir ADDED! \033[0K\r"
Run Code Online (Sandbox Code Playgroud)

以下是一个可以运行以了解其行为的小示例:

#!/bin/bash
for pc in $(seq 1 100); do
    echo -ne "$pc%\033[0K\r"
    sleep 1
done
echo
Run Code Online (Sandbox Code Playgroud)


Ant*_*via 15

其余的答案非常好,但只是想添加一些额外的信息,以防有人来这里寻找替换/更新多线回波的解决方案.

所以我想和大家分享一个例子.在CentOS系统上尝试了以下脚本,并使用"timedatectl"命令,该命令基本上打印了系统的一些详细时间信息.

我决定使用该命令,因为它的输出包含多行,并且适用于下面的示例:

#!/bin/bash
while true; do
  COMMAND=$(timedatectl) #Save command result in a var.
  echo "$COMMAND" #Print command result, including new lines.

  sleep 3 #Keep above's output on screen during 3 seconds before clearing it

  #Following code clears previously printed lines
  LINES=$(echo "$COMMAND" | wc -l) #Calculate number of lines for the output previously printed
  for (( i=1; i <= $(($LINES)); i++ ));do #For each line printed as a result of "timedatectl"
    tput cuu1 #Move cursor up by one line
    tput el #Clear the line
  done

done
Run Code Online (Sandbox Code Playgroud)

以上将timedatectl永远打印" " 的结果,并将用更新的结果替换先前的回声.

我必须提一下,这段代码只是一个例子,但根据您的需要,可能不是最适合您的解决方案.几乎相同(至少在视觉上)的类似命令是" watch -n 3 timedatectl".

但这是一个不同的故事.:)

希望有所帮助!


Ser*_*reu 15

我使用 printf,它更短,因为它不需要标志来完成工作:

printf "\rMy static $myvars composed text"
Run Code Online (Sandbox Code Playgroud)


小智 5

这是非常有用的,请尝试并根据需要进行更改。

#!/bin/bash
for load in $(seq 1 100); do
    echo -ne "$load % downloded ...\r"
    sleep 1
done
echo "100"
echo "Loaded ..."
Run Code Online (Sandbox Code Playgroud)