Cómo mostrar y actualizar el eco en la misma línea

Tengo lo siguiente en Bash (en 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 

Pero deseo hacerlo para que el “eco” muestre el siguiente eco en la línea siguiente (No concatenar con la última salida de eco, sino que la reemplaza) para que parezca que se está actualizando. Similar a cómo una barra de progreso con porcentaje se mostraría en la misma línea.

Bueno, no leí correctamente la página de man echo del man echo para esto.

echo tenía 2 opciones que podrían hacer esto si agregué un tercer carácter de escape.

Las 2 opciones son -n y -e .

-n no generará la nueva línea final. Entonces eso me ahorra ir a una nueva línea cada vez que hago eco de algo.

-e me permitirá interpretar símbolos de escape de barra invertida.

Adivina qué símbolo de escape quiero usar para esto: \r . Sí, el retorno de carro me devolvería al inicio y parecerá que estoy actualizando en la misma línea.

Entonces la línea de eco se vería así:

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

Tuve que escapar del símbolo de escape para que Bash no lo matara. es por eso que ves 2 \ símbolos allí.

Como menciona William, printf también puede hacer tareas similares (e incluso más extensas) como esta.

Si lo he entendido bien, puede reemplazarlo con la siguiente línea:

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

Aquí hay un pequeño ejemplo que puede ejecutar para comprender su comportamiento:

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

El rest de las respuestas son bastante buenas, pero solo quería agregar algo de información adicional en caso de que alguien venga aquí buscando una solución para reemplazar / actualizar un eco multilínea.

Entonces me gustaría compartir un ejemplo con todos ustedes. El siguiente script fue probado en un sistema CentOS y usa el comando “timedatectl” que básicamente imprime información de tiempo detallada de su sistema.

Decidí usar ese comando ya que su salida contiene múltiples líneas y funciona perfectamente para el siguiente ejemplo:

 #!/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 

Lo anterior imprimirá el resultado de " timedatectl " para siempre y reemplazará el eco anterior con resultados actualizados.

Debo mencionar que este código es solo un ejemplo, pero tal vez no sea la mejor solución para usted según sus necesidades. Un comando similar que haría casi lo mismo (al menos visualmente) es " watch -n 3 timedatectl ".

Pero esa es una historia diferente. 🙂

¡Espero que ayude!

Mi forma favorita se llama do sleep to 50. Aquí, la variable debe usarse dentro de las declaraciones de eco.

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

Esto es útil, por favor pruébalo y cámbialo según sea necesario.

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