Как показать и обновить эхо на одной строке

У меня есть следующее в 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

Но я хочу сделать так, чтобы "эхо" отображало следующее эхо на следующей строке (не конкатенация с последним выходом эха, а замена его), чтобы он выглядел так, как будто он обновляется. Аналогично тому, как индикатор выполнения с процентом будет отображаться в одной строке.

Ответ 1

Ну, я не правильно прочитал страницу man echo для этого.

В echo было 2 варианта, которые могли бы сделать это, если бы я добавил третий escape-символ.

2 варианта: -n и -e.

-n не выводит конечную новую строку. Так что это спасает меня от перехода на новую строку каждый раз, когда я что-то повторяю.

-e позволит мне интерпретировать символы обратного слэша.

Угадайте, какой escape-символ я хочу использовать для этого: \r. Да, возврат каретки вернет меня к началу, и он будет визуально выглядеть так, как будто я обновляюсь в той же строке.

Итак, эхо-строка будет выглядеть так:

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

Мне пришлось сбежать из escape-символа, поэтому Bash не убьет его. поэтому вы видите там 2 \.

Как упоминалось Уильямом, printf также может выполнять аналогичные (и даже более обширные) задачи, подобные этому.

Ответ 2

Если я хорошо понял, вы можете заставить его заменить ваше эхо на следующую строку:

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

Ответ 3

Остальные ответы довольно хороши, но я просто хотел добавить дополнительную информацию на случай, если кто-то придет сюда в поисках решения для замены/обновления многострочного эха.

Поэтому я хотел бы поделиться примером со всеми вами. Следующий скрипт был опробован в системе 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 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 ".

Но это другая история. :)

Надеюсь, это поможет!

Ответ 4

Это полезно, пожалуйста, попробуйте и измените по мере необходимости.

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

Ответ 5

Мой любимый способ называется do sleep to 50. здесь i должен использовать переменную внутри операторов echo.

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

Ответ 6

Вы можете попробовать это.. Моя собственная версия этого..

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                  "