私のbashスクリプトは次のように見えます:
echo "Description:"
while [ $finishInput -eq 0 ]; do
read tmp
desc="$desc"$'\n'"$tmp"
if [ -z "$tmp" ]; then
finishInput="1"
fi
done
echo -n "Maintainer:"
read maintainer
空行が渡されるまでdesc varを読み取ります。その後、私は他のものを読みたいです。
現在のスクリプトを実行すると、次のようになります。
Description:
Line 1
Line 2
Maintainer:
最後の空の行を「Maintainer:」で上書きします。
私は解決策を探しましたが、次のような提案のみを見つけました
echo -n "Old line"
echo -e "\r new line"
行に残り、上書きします。私の場合、これは不可能です。
"\e[1A"
を使用してください。
例では、同じ行のテキストを削除します。
$ echo -n "Old line"; echo -e "\e[0K\r new line"
new line
前の行に戻りたい場合は、\ e [1Aを使用します。
$ echo "Old line"; echo -en "\e[1A"; echo -e "\e[0K\r new line"
new line
N行上に移動する場合は、\e[<N>A
を使用します。
素晴らしい エスケープシーケンスに関するガイド を見つけ、ここでの議論のいくつかを拡張したかった.
ターミナルに書き出すときは、テキストエディタで書くときと同じように、非表示カーソルを移動します。 echo
を使用すると、カーソルを次の行に移動する改行文字で出力が自動的に終了します。
$ echo "Hello" && echo " World"
Hello
World
-n
を使用して新しい行を防ぐことができます。この後に再度エコーすると、その行の末尾に追加されます
$ echo -n "Hello" && echo " World"
Hello World
カーソルは元のままなので、それ自体では、-n
を使用して前の行を上書きすることはできません。カーソルを左に移動する必要があります。それを行うには、エスケープシーケンスを与える必要があります。エスケープシーケンスは、-e
で使用することをecho
に知らせ、カーソルを移動するリターンキャリッジ\r
を提供してカーソルを移動します。行の始まり。
$ echo -n "Hello" && echo -e "\rWorld"
World
それはうまくいったように見えるかもしれませんが、何が起こるかを見てください
$ echo -n "A longer sentance" && echo -e "\rShort sentance"
Short sentancence
余分な文字が表示されますか?単に行に書き込むと、それらを書いた文字が変わるだけです。
これを修正するため、上記の受け入れられた回答では、エスケープ文字\e[0K
を使用して、カーソルの後、カーソルが左に移動した後にすべてを消去します。つまり、\r
を先頭に移動\e[0K
を消去して終了します。
$ echo -n "A longer sentance" && echo -e "\r\e[0KShort sentance"
Short sentance
Important\e
はエスケープシーケンスを開始しますが、zsh
では機能しますが、sh
では機能せず、必ずしもbash
ではありませんが、\033
はすべてで機能しますそのうちの。スクリプトをどこでも動作させたい場合は、\033
を設定する必要があります
$ echo -n "A longer sentance" && echo -e "\r\033[0KShort sentance"
Short sentance
ただし、エスケープ文字を使用するとさらに便利になります。たとえば、\033[1A
はカーソルを前の行に移動するため、前のエコーで-n
は不要です。
$ echo "A longer sentance" && echo -e "\r\033[1A\033[0KShort sentance"
Short sentance
\r
先頭に移動\033[1A
上に移動\033[0K
最後に消去
最後に、これは私の本では少し面倒なので、これを関数に変えることができます:
overwrite() { echo -e "\r\033[1A\033[0K$@"; }
$@
を使用すると、関数のすべてのパラメーターが文字列に入れられます
$ echo Longer sentance && overwrite Short sentence
Short sentence
もっと知りたい人に役立つことを願っています。
Dennis Williamsons Comment から関数を作成しました:
function clearLastLine() {
tput cuu 1 && tput el
}
デニス・ウィリアムソンに感謝
改行文字echo -n "Something"
なしでエコーする場合、次のエコーで\r
を使用して、 'cursor'を行の先頭echo -e "\\rOverwrite something"
。
#!/bin/bash
CHECK_MARK="\033[0;32m\xE2\x9C\x94\033[0m"
echo -e "\n\e[4mDoing Things\e[0m"
echo -n "doing thing 1..."
sleep 1
echo -e "\\r${CHECK_MARK} thing 1 done"
新しい文字列が古い文字列よりも短い場合でも、古い文字列の末尾が表示されることに注意してください。上記のgifのdone..
に注意してください。
#!/bin/bash
echo "Description:"
while test -z $finishInput; do
read -s tmp
desc="$desc"$'\n'"$tmp"
if [ -z "$tmp" ]; then
finishInput=1
else
echo $tmp
fi
#echo "fi="$finishInput;
done
echo -n "Maintainer:"
read maintainer
このソリューションは空の行を回避しますが、行が完了するまで入力はエコーされません。
ヒント:bashの私のバージョンは「[$ finishInput -eq 0]」を受け入れませんでした。
スクリプトをループで実行し、スクロールバックを爆破したくない場合は、次のパターンを使用できます。
while sleep 10s; do
echo -n $(script)
echo -n -e "\e[0K\r"
done
script
コマンドを独自のものに置き換えるだけです。