2012-09-27 23 views
67

更新回音,我有以下的击(在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 

但我想使它这样的“回声”表示下一行下面的回声(不与最后的echo输出连接,但将其替换),以使其看起来像正在更新。类似于具有百分比的进度条如何显示在同一行上。

回答

115

那么我没有正确阅读man echo这一页。

回声有2个选项可以做到这一点,如果我添加了第三个转义字符。

2个选项是-n-e

-n不会输出结尾的换行符。因此,每当我回应某些内容时,我都不用再换一个新的线。

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

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

所以回声线是这样的:

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

我不得不逃离逃逸符号这样的Bash不会杀死它。这就是为什么你会在那里看到2 \符号。

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

+8

只是对未来的一个提示:printf会做同样的事情,没有任何选项。优点是printf在每个环境和操作系统中的行为通常都是相似的,而echo有时表现得非常不同。对于跨平台脚本(或者如果你认为你可能会关心这一点),使用printf是最佳实践。 –

+0

真棒@WilliamTFroggard谢谢你的朋友。 –

+3

'printf a; printf b'输出'ab' ---'printf a \\ r; printf b'输出'b' ---'printf a \\ r;睡1; printf b''输出'a',然后'b' – XavierStuvw

50

如果我已经了解好了,你可以把它与下面的行替换您的回音:

echo -ne "Movie $movies - $dir ADDED! \033[0K\r" 

这里,您可以运行,了解其行为的一个小例子:

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

在zsh上看起来'K'并不是必要的,事实上它会以字母K的形式出现。 – mknaf

+1

很好的例子 - 对我来说,开始时的hash bang是关键 –

9

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

所以我想和大家分享一个例子。在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 

以上将打印的结果“timedatectl”永远将取代之前的回声更新结果。

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

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

希望帮助!

+1

经过测试。通过。谢谢 – XavierStuvw

1

我最喜欢的方式叫睡觉到50.这里i变量需要在echo语句里面使用。

for i in $(seq 1 50); do 
    echo -ne "$i%\033[0K\r" 
    sleep 50 
done 
echo "ended" 
0

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

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