116

bashで経過秒数を表示するプログレスバーを実装したいと思います。このためには、画面に表示されている最後の行を消去する必要があります(コマンド「clear」はすべての画面を消去しますが、プログレスバーの行だけを消去して新しい情報に置き換える必要があります)。

最終結果は次のようになります。

$ Elapsed time 5 seconds

次に、10秒後に、この文(画面の同じ位置)を次のように置き換えます。

$ Elapsed time 15 seconds
4

8 に答える 8

210

キャリッジリターン自体は、カーソルを行の先頭に移動するだけです。出力の新しい各行が少なくとも前の行と同じ長さであれば問題ありませんが、新しい行が短い場合、前の行は完全に上書きされません。例:

$ echo -e "abcdefghijklmnopqrstuvwxyz\r0123456789"
0123456789klmnopqrstuvwxyz

新しいテキストの行を実際にクリアするには、 :\033[Kの後に追加します。\r

$ echo -e "abcdefghijklmnopqrstuvwxyz\r\033[K0123456789"
0123456789

http://en.wikipedia.org/wiki/ANSI_escape_code

于 2011-07-21T10:06:36.580 に答える
124

\rでキャリッジリターンをエコーし​​ます

seq 1 1000000 | while read i; do echo -en "\r$i"; done

男エコーから:

-n     do not output the trailing newline
-e     enable interpretation of backslash escapes

\r     carriage return
于 2010-03-05T16:08:38.650 に答える
23

Derek Veitの答えは、線の長さが端子の幅を超えない限りうまく機能します。そうでない場合は、次のコードでジャンク出力を防止します。

行が初めて書き込まれる前に、

tput sc

これにより、現在のカーソル位置が保存されます。これで、行を印刷するときはいつでも、

tput rc
tput ed
echo "your stuff here"

最初に保存されたカーソル位置に戻り、次にカーソルから下に向かって画面をクリアし、最後に出力を書き込みます。

于 2013-09-20T12:04:48.060 に答える
14

\033メソッドは私にはうまくいきませんでした。\ rメソッドは機能しますが、実際には何も消去せず、カーソルを行の先頭に置くだけです。したがって、新しい文字列が古い文字列よりも短い場合は、行の終わりに残りのテキストが表示されます。結局、tputが最善の方法でした。カーソル以外にも用途があり、多くのLinuxおよびBSDディストリビューションにプリインストールされているため、ほとんどのbashユーザーが利用できるはずです。

#/bin/bash
tput sc # save cursor
printf "Something that I made up for this string"
sleep 1
tput rc;tput el # rc = restore cursor, el = erase to end of line
printf "Another message for testing"
sleep 1
tput rc;tput el
printf "Yet another one"
sleep 1
tput rc;tput el

遊ぶための小さなカウントダウンスクリプトは次のとおりです。

#!/bin/bash
timeout () {
    tput sc
    time=$1; while [ $time -ge 0 ]; do
        tput rc; tput el
        printf "$2" $time
        ((time--))
        sleep 1
    done
    tput rc; tput ed;
}

timeout 10 "Self-destructing in %s"
于 2015-01-14T20:45:22.183 に答える
12

進行状況の出力が複数行の場合、またはスクリプトがすでに改行文字を出力している場合は、次のように行をジャンプできます。

printf "\033[5A"

これにより、カーソルが5行上にジャンプします。次に、必要なものを上書きできます。

それがうまくいかない場合は、printf "\e[5A"またはecho -e "\033[5A"を試すことができます。これは同じ効果があるはずです。

基本的に、エスケープシーケンスを使用すると、画面内のほとんどすべてを制御できます。

于 2017-05-19T22:16:12.443 に答える
4

キャリッジリターン文字を使用します。

echo -e "Foo\rBar" # Will print "Bar"
于 2010-03-05T16:09:25.717 に答える
2

キャリッジリターンを配置することで実現できます\r

1行のコードでprintf

for i in {10..1}; do printf "Counting down: $i\r" && sleep 1; done

またはとecho -ne

for i in {10..1}; do echo -ne "Counting down: $i\r" && sleep 1; done
于 2018-09-27T04:59:57.513 に答える
0

前の行をクリアしたいだけの場合は、次の方法でうまくいく可能性があります。

printf '\033[1A\033[K'

複数行の場合は、ループで使用します。

for i in {1..10}; do
    printf '\033[1A\033[K'
done

これにより、最後の10行がクリアされます。

于 2022-02-27T16:00:56.423 に答える