如何在同一行显示和更新回声

时间:2012-09-27 18:58:49

标签: bash

我在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”在下一行显示以下echo(不与最后一个echo输出连接但是替换它),以使它看起来像是在更新。类似于带百分比的进度条如何显示在同一行上。

7 个答案:

答案 0 :(得分:160)

我没有正确阅读man echo页面。

如果我添加了第3个转义字符,

echo有2个选项可以执行此操作。

2个选项为-n-e

-n不会输出尾随换行符。因此,每当我回应一些东西时,我就不会去新线。

-e将允许我解释反斜杠转义符号。

猜猜我想要使用哪个转义符号:\r。是的,回车会把我送回到开头,看起来我会在同一条线上更新。

所以回声线看起来像这样:

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

我必须逃脱逃生符号,所以Bash不会杀死它。这就是为什么你会看到2个\符号的原因。

正如威廉所说,printf也可以做类似(甚至更广泛)的任务。

答案 1 :(得分:57)

如果我理解得很好,你可以用以下一行替换你的回声:

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

答案 2 :(得分:13)

其余的答案非常好,但只是想添加一些额外的信息,以防有人来这里寻找替换/更新多线回声的解决方案。

所以我想和大家分享一个例子。在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

以上将打印&#34; timedatectl&#34;的结果永远,并将用更新的结果取代之前的回声。

我必须提到这段代码只是一个例子,但根据您的需要,可能不是最适合您的解决方案。 几乎相同(至少在视觉上)的类似命令是&#34; watch -n 3 timedatectl&#34;。

但这是一个不同的故事。 :)

希望有所帮助!

答案 3 :(得分:2)

这是有用的,请尝试并根据需要进行更改。

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

答案 4 :(得分:2)

您可以尝试一下。我自己的版本。

<script>
      // Already Initialized Firebase


      var text = document.getElementById('name');
      var email = document.getElementById('email');
      var password = document.getElementById('password');

      var button = document.getElementById('button');


      var profilePic = document.getElementById('profilePic');





      function registerUser(){



      var Name = text.value;
      var Email = email.value;
      var Password = password.value;
      var Image = profilePic.files[0];
      window.alert(Name)

      firebase.auth().createUserWithEmailAndPassword(Email, Password).catch(function(error) {
      // Handle Errors here.
      var errorCode = error.code;
      var errorMessage = error.message;
      // ...
    });

      var user = firebase.auth().currentUser;

      var uid = user.uid;

      var dbRefUid = firebase.database().ref().child('Web App').child('Users');

      dbRefUid.set(uid);

      var dbRefName = firebase.database().ref().child('Web App').child('Users').child(uid).child('Name');
      var dbRefEmail = firebase.database().ref().child('Web App').child('Users').child(uid).child('Email');
      var dbRefPassword = firebase.database().ref().child('Web App').child('Users').child(uid).child('Password');
      var dbRefProfilepicUrl = firebase.database().ref().child('Web App').child('Users').child(uid).child('Profilepicture URL');


      dbRefName.set(Name);
      dbRefEmail.set(Email);
      dbRefPassword.set(Password);


      var imageRoot = firebase.storage().ref('users/' + "profile");

      imageRoot.put(Image);


      var uploadTask = imageRoot.put(Image);

    // Register three observers:
    // 1. 'state_changed' observer, called any time the state changes
    // 2. Error observer, called on failure
    // 3. Completion observer, called on successful completion
    uploadTask.on('state_changed', function(snapshot){
      // Observe state change events such as progress, pause, and resume
      // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
      var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
      console.log('Upload is ' + progress + '% done');
      switch (snapshot.state) {
        case firebase.storage.TaskState.PAUSED: // or 'paused'
          console.log('Upload is paused');
          break;
        case firebase.storage.TaskState.RUNNING: // or 'running'
          console.log('Upload is running');
          break;
      }
    }, function(error) {
      // Handle unsuccessful uploads
    }, function() {
      // Handle successful uploads on complete
      // For instance, get the download URL: https://firebasestorage.googleapis.com/...
      uploadTask.snapshot.ref.getDownloadURL().then(function(downloadURL) {

        dbRefProfilepicUrl.set(downloadURL);

        console.log('File available at', downloadURL);
      });
    });

      firebase.auth().signOut().then(function() {
        window.alert("Sign Out")

      // Sign-out successful.
    }).catch(function(error) {
      // An error happened.
    });

      }
    </script>

答案 5 :(得分:2)

我使用 printf,它更短,因为它不需要标志来完成工作:

printf "\rMy static $myvars composed text"

答案 6 :(得分:1)

我最喜欢的方式叫做睡眠到50.这里i变量需要在echo语句中使用。

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