2012-09-27 32 views
67

Tôi có sau trong Bash (Trong Linux)Làm thế nào để hiển thị và cập nhật tiếng vang trên cùng một dòng

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

Trả lời

115

Tôi cũng không đọc chính xác trang man echo cho việc 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.

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

-n sẽ không xuất dòng mới. Vì vậy, điều đó giúp tôi không phải đi đến một dòng mới mỗi lần tôi lặp lại điều gì đó.

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

Đoán biểu tượng thoát nào tôi muốn sử dụng cho điều này: \r. Có, vận chuyển trở lại sẽ gửi cho tôi trở lại để bắt đầu và nó sẽ trực quan trông giống như tôi đang cập nhật trên cùng một dòng.

Vì vậy, các dòng vang sẽ trông như thế này:

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

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

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

+8

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

+0

Awesome @WilliamTFroggard cảm ơn bạn của bạn. –

+3

'printf a; printf b' kết quả đầu ra 'ab' ---' printf a \\ r; printf b' kết quả đầu ra 'b' ---' printf a \\ r; ngủ 1; printf b' output 'a', sau đó' b' – XavierStuvw

50

Nếu tôi đã hiểu rõ, bạn có thể lấy nó thay thế tiếng vang của bạn với các dòng sau:

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

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

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

Có vẻ như trên zsh, 'K' là không cần thiết và trên thực tế được đưa ra dưới dạng chữ K. – mknaf

+1

Ví dụ tuyệt vời - cho tôi băm băm ở đầu là khóa –

9

Phần còn lại của 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 một giải pháp để thay thế/cập nhật một echo đa âm.

Vì vậy, tôi muốn chia sẻ một ví dụ với tất cả các bạn. Kịch bản sau đã được thử trên một hệ thống CentOS và sử dụng lệnh "timedatectl" mà về cơ bản in 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 đó khi nó được đầu ra chứa nhiều đường và hoạt động hoàn hảo cho các 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ế tiếng vang trước đó với cập nhật các kết quả.

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ư giống nhau (ít nhất là trực quan) là "watch -n 3 timedatectl".

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

Hy vọng điều đó sẽ hữu ích!

+1

Đã kiểm tra. Vượt qua. Cảm ơn – XavierStuvw

1

Cách yêu thích của tôi được gọi là ngủ ở mức 50. ở đây i cần phải được sử dụng 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" 
0

Điều này rất hữu ích, vui lòng thử 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 ..." 
Các vấn đề liên quan