วิธีแสดงและอัปเดตเสียงสะท้อนในบรรทัดเดียวกัน


113

ฉันมีสิ่งต่อไปนี้ใน 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

แต่ฉันต้องการทำให้เป็นเช่นนั้น "เสียงสะท้อน" จะแสดงเสียงสะท้อนต่อไปนี้ในบรรทัดถัดไป (ไม่เชื่อมต่อกับเอาต์พุตเสียงสะท้อนสุดท้าย แต่แทนที่) เพื่อให้ดูเหมือนว่ากำลังอัปเดต คล้ายกับการที่แถบความคืบหน้าพร้อมเปอร์เซ็นต์จะแสดงในบรรทัดเดียวกัน

คำตอบ:


197

ฉันอ่านman echoหน้านี้ไม่ถูกต้อง

echo มี 2 ตัวเลือกที่ทำได้ถ้าฉันเพิ่มอักขระหลีกตัวที่ 3

2 ตัวเลือกคือ-nและ-e.

-nจะไม่ส่งออกบรรทัดใหม่ต่อท้าย นั่นช่วยให้ฉันไม่ต้องขึ้นบรรทัดใหม่ทุกครั้งที่ฉันสะท้อนอะไรบางอย่าง

-e จะช่วยให้ฉันตีความสัญลักษณ์การหลีกเลี่ยงแบ็กสแลช

เดาว่าฉันต้องการใช้สัญลักษณ์หลบหนีอะไร: \r. ใช่การกลับรถจะส่งฉันกลับไปที่จุดเริ่มต้นและจะดูเหมือนว่าฉันกำลังอัปเดตในบรรทัดเดียวกัน

ดังนั้นเส้นสะท้อนจะมีลักษณะดังนี้:

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

ฉันต้องหนีสัญลักษณ์หนีเพื่อ Bash จะได้ไม่ฆ่ามัน นั่นคือเหตุผลที่คุณเห็น\สัญลักษณ์2 ตัวในนั้น

ดังที่วิลเลียมกล่าวไว้printfยังสามารถทำงานที่คล้ายกัน (และกว้างขวางมากขึ้น) เช่นนี้


12
หมายเหตุสำหรับอนาคต: printf จะทำสิ่งเดียวกันทุกประการโดยไม่มีตัวเลือกใด ๆ ข้อดีคือโดยทั่วไป printf จะทำงานคล้าย ๆ กันในทุกสภาพแวดล้อมและระบบปฏิบัติการในขณะที่บางครั้งเสียงสะท้อนอาจทำงานแตกต่างกันมาก สำหรับสคริปต์ข้ามแพลตฟอร์ม (หรือถ้าคุณคิดว่าคุณอาจสนใจเรื่องนั้น) การใช้ printf เป็นแนวทางปฏิบัติที่ดีที่สุด
William T Froggard

8
printf a; printf bเอาท์พุทab--- printf a\\r; printf bเอาท์พุทb--- printf a\\r; sleep 1; printf bเอาท์พุทaแล้วb
XavierStuvw

64

หากฉันเข้าใจดีแล้วคุณสามารถเปลี่ยนเสียงสะท้อนของคุณด้วยบรรทัดต่อไปนี้:

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

ดูเหมือนว่าบน zsh Kไม่จำเป็นและในความเป็นจริงจะออกเป็นตัวอักษร K.
mknaf

1
ตัวอย่างที่ดี - สำหรับฉันแฮชปังที่จุดเริ่มต้นคือกุญแจสำคัญ
เฟลิกซ์อีฟ

23

คำตอบที่เหลือค่อนข้างดี แต่แค่ต้องการเพิ่มข้อมูลเพิ่มเติมในกรณีที่มีคนมาที่นี่เพื่อหาวิธีแก้ไข / อัปเดตเสียงสะท้อนหลายสาย

ผมจึงอยากจะแบ่งปันตัวอย่างให้ทุกท่าน สคริปต์ต่อไปนี้ได้รับการทดลองบนระบบ 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

ข้างต้นจะพิมพ์ผลลัพธ์เป็น " timedatectl" ตลอดไปและจะแทนที่เสียงสะท้อนก่อนหน้าด้วยผลลัพธ์ที่อัปเดต

ฉันต้องพูดถึงว่ารหัสนี้เป็นเพียงตัวอย่างเท่านั้น แต่อาจไม่ใช่ทางออกที่ดีที่สุดสำหรับคุณทั้งนี้ขึ้นอยู่กับความต้องการของคุณ คำสั่งที่คล้ายกันซึ่งเกือบจะเหมือนกัน (อย่างน้อยก็เป็นภาพ) คือ " watch -n 3 timedatectl"

แต่นั่นเป็นเรื่องที่แตกต่าง :)

หวังว่าจะช่วยได้!


3

สิ่งนี้มีประโยชน์แตกต่างกันไปโปรดลองและเปลี่ยนแปลงตามความจำเป็น

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

3

ลองดูได้ครับ .. เวอร์ชั่นของผมเอง ..

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

วิธีที่ฉันชอบเรียกว่า do the sleep ถึง 50 iตัวแปรที่นี่จำเป็นต้องใช้ภายในคำสั่ง echo

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

นี่เป็นสิ่งที่ดี แต่เคอร์เซอร์บดบังอักขระตัวแรก ฉันเดาว่าช่องว่างบางส่วนในเสียงสะท้อนอาจอยู่ในบริเวณนั้น
มาราธอน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.