144

私は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

ただし、「echo」が次の行に次のエコーを表示するようにしたいので(最後のエコー出力と連結せずに置き換えます)、更新中のように見せます。パーセント付きのプログレスバーが同じ行に表示されるのと似ています。

4

7 に答える 7

243

man echoさて、私はこれのページを正しく読みませんでした。

echoには、3番目のエスケープ文字を追加した場合にこれを実行できる2つのオプションがありました。

-n2つのオプションはとです-e

-n末尾の改行は出力されません。そのため、何かをエコーするたびに新しい行に移動する必要がなくなります。

-eバックスラッシュエスケープ記号を解釈できるようになります。

これに使用したいエスケープ記号を推測します\r。はい、キャリッジリターンを使用すると最初に戻り、同じ行で更新しているように見えます。

したがって、エコーラインは次のようになります。

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

Bashがエスケープ記号を殺さないように、エスケープ記号をエスケープする必要がありました。そのため\、そこに2つのシンボルが表示されます。

ウィリアムが述べたようにprintf、このような同様の(そしてさらに広範囲の)タスクを実行することもできます。

于 2012-09-27T19:10:14.490 に答える
71

私がよく理解している場合は、エコーを次の行に置き換えて取得できます。

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
于 2012-09-27T19:11:57.320 に答える
30

残りの答えはかなり良いですが、誰かがマルチラインエコーを置き換える/更新するための解決策を探してここに来る場合に備えて、いくつかの追加情報を追加したかっただけです。

ですから、皆さんと例を共有したいと思います。次のスクリプトは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」です。

しかし、それは別の話です。:)

お役に立てば幸いです。

于 2016-12-16T19:40:34.317 に答える
10

私はprintfを使用していますが、作業を行うためにフラグを必要としないため、短くなっています。

printf "\rMy static $myvars composed text"
于 2020-12-29T18:22:08.763 に答える
6

これは便利です。試してみて、必要に応じて変更してください。

#!/bin/bash
for load in $(seq 1 100); do
    echo -ne "$load % downloded ...\r"
    sleep 1
done
echo "100"
echo "Loaded ..."
于 2018-02-17T12:50:32.990 に答える
4

あなたはこれを試すことができます..それの私自身のバージョン..

funcc() {
while true ; do 
for i in \| \/ \- \\ \| \/ \- \\; do 
  echo -n -e "\r$1  $i  "
sleep 0.5
done  
#echo -e "\r                                                                                      "
[ -f /tmp/print-stat ] && break 2
done
}

funcc "Checking Kubectl" & &>/dev/null
sleep 5
touch /tmp/print-stat
echo -e "\rPrint Success                  "
于 2019-01-11T09:58:05.680 に答える
3

私のお気に入りの方法は、50までスリープすることです。ここでは、iechoステートメント内で変数を使用する必要があります。

for i in $(seq 1 50); do
  echo -ne "$i%\033[0K\r"
  sleep 50
done
echo "ended"
于 2018-01-16T17:49:58.927 に答える