Cách hiển thị và cập nhật tiếng vọng trên cùng một dòng


112

Tôi có những thứ sau trong Bash (Trong 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

Nhưng tôi muốn làm cho nó để "tiếng vang" hiển thị tiếng vọng sau trên dòng tiếp theo (Không nối với đầu ra tiếng vọng cuối cùng nhưng thay thế nó) để làm cho nó trông giống như nó đang cập nhật. Tương tự như cách một thanh tiến trình với phần trăm sẽ hiển thị trên cùng một dòng.

Câu trả lời:


196

Vâng, tôi đã không đọc chính xác man echotrang này.

echo có 2 tùy chọn có thể thực hiện việc này nếu tôi thêm ký tự thoát thứ 3.

2 tùy chọn là -n-e.

-nsẽ không xuất ra dòng mới ở cuối. Vì vậy, điều đó giúp tôi không phải chuyển sang dòng mới mỗi khi tôi lặp lại nội dung nào đó.

-e sẽ cho phép tôi giải thích các ký hiệu thoát dấu gạch chéo ngược.

Đoán những gì biểu tượng thoát Tôi muốn sử dụng cho việc này: \r. Có, ký tự xuống dòng sẽ đưa tôi trở lại ban đầu và nó trông giống như tôi đang cập nhật trên cùng một dòng.

Vì vậy, dòng tiếng vang sẽ giống như sau:

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

Tôi phải thoát khỏi biểu tượng thoát để Bash không giết nó. đó là lý do tại sao bạn thấy 2 \biểu tượng trong đó.

Như đã đề cập bởi William, printfcũng có thể làm các nhiệm vụ tương tự (và thậm chí rộng hơn) như thế này.


12
Chỉ cần một lưu ý cho tương lai: printf sẽ làm chính xác điều tương tự, không có bất kỳ tùy chọn nào. Ưu điểm là printf thường hoạt động giống nhau trong mọi môi trường và hệ điều hành, trong khi tiếng vọng đôi khi có thể hoạt động rất khác nhau. Đối với các tập lệnh đa nền tảng (hoặc nếu bạn nghĩ rằng bạn có thể quan tâm đến điều đó), sử dụng printf là phương pháp hay nhất.
William T Froggard

8
printf a; printf bkết quả đầu ra ab--- printf a\\r; printf bđầu ra b--- printf a\\r; sleep 1; printf bkết quả đầu ra a, sau đób
XavierStuvw

64

Nếu tôi đã hiểu rõ, bạn có thể yêu cầu nó thay thế tiếng vọng của bạn bằng dòng sau:

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

Đây là một ví dụ nhỏ mà bạn có thể chạy để hiểu hành vi của nó:

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

Dường như trên zsh sự Klà không cần thiết và trong thực tế được đưa ra như chữ K.
mknaf

1
Ví dụ tuyệt vời - đối với tôi, tiếng nổ băm lúc đầu là chìa khóa
Felix Eve

22

Phần còn lại của các câu trả lời là khá tốt, nhưng chỉ muốn thêm một số thông tin bổ sung trong trường hợp ai đó đến đây tìm kiếm giải pháp để thay thế / cập nhật một tiếng vọng đa dòng.

Vì vậy, tôi muốn chia sẻ một ví dụ với tất cả các bạn. Tập lệnh sau đã được thử trên hệ thống CentOS và sử dụng lệnh "timedatectl" về cơ bản sẽ in ra một số thông tin thời gian chi tiết của hệ thống của bạn.

Tôi đã quyết định sử dụng lệnh đó vì đầu ra của nó chứa nhiều dòng và hoạt động hoàn hảo cho ví dụ dưới đây:

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

Ở trên sẽ in kết quả của " timedatectl" mãi mãi và sẽ thay thế echo trước đó bằng kết quả được cập nhật.

Tôi phải đề cập rằng mã này chỉ là một ví dụ, nhưng có thể không phải là giải pháp tốt nhất cho bạn tùy thuộc vào nhu cầu của bạn. Một lệnh tương tự sẽ thực hiện gần như tương tự (ít nhất là về mặt trực quan) là " watch -n 3 timedatectl".

Nhưng đó là một câu chuyện khác. :)

Hy vọng rằng sẽ giúp!


3

Điều này rất hữu ích, vui lòng thử nó và thay đổi theo yêu cầu.

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

3

Bạn có thể thử cái này .. Phiên bản của riêng tôi ..

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                  "

1

Cách yêu thích của tôi được gọi là do the sleep to 50. ở đây ibiến cần được sử dụng bên trong các câu lệnh echo.

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

điều này rất hay, nhưng con trỏ che khuất ký tự đầu tiên. Tôi đoán một số khoảng trống trong tiếng vang có thể xen vào đó.
marathon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.