एक ही लाइन पर इको को कैसे दिखाना और अपडेट करना है


112

मेरे पास 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

लेकिन मैं इसे इतना बनाना चाहता हूं कि "इको" अगली पंक्ति पर निम्नलिखित प्रतिध्वनि दिखाता है (अंतिम गूंज आउटपुट के साथ नहीं बल्कि इसे बदलें) ताकि यह अपडेट हो जाए। इसी तरह प्रतिशत के साथ प्रगति पट्टी एक ही रेखा पर कैसे दिखाई देगी।

जवाबों:


196

वैसे मैंने इसके लिए man echoपेज को सही से नहीं पढ़ा ।

इको में 2 विकल्प थे जो ऐसा कर सकते थे यदि मैं एक 3 से बच चरित्र जोड़ देता।

2 विकल्प हैं -nऔर -e

-nअनुगामी न्यूलाइन को आउटपुट नहीं करेगा। ताकि हर बार जब मैं किसी चीज की गूंज करूं तो मुझे एक नई लाइन में जाने से बचाता है।

-e मुझे बैकस्लैश एस्केप प्रतीकों की व्याख्या करने की अनुमति देगा।

लगता है कि मैं इसके लिए किस प्रतीक का उपयोग करना चाहता हूं \r:। हां, कैरिज वापसी मुझे शुरुआत में वापस भेज देगी और यह नेत्रहीन लगेगा जैसे मैं एक ही लाइन पर अपडेट कर रहा हूं।

तो प्रतिध्वनि रेखा इस तरह दिखाई देगी:

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

मुझे बच के प्रतीक से बचना था ताकि बैश उसे मार न दे। यही कारण है कि आप \वहाँ में 2 प्रतीक देखते हैं ।

जैसा कि विलियम ने उल्लेख किया है, printfइस तरह के (और भी अधिक व्यापक) कार्यों को भी कर सकते हैं।


12
भविष्य के लिए बस एक नोट: प्रिंटफ बिल्कुल वैसा ही काम करेगा, बिना किसी विकल्प के। फायदा यह है कि प्रिंटफ आमतौर पर हर वातावरण और ओएस में समान व्यवहार करता है, जबकि इको कभी-कभी बहुत अलग तरीके से व्यवहार कर सकता है। क्रॉस-प्लेटफ़ॉर्म स्क्रिप्ट के लिए (या यदि आपको लगता है कि आप कभी भी इस बारे में परवाह कर सकते हैं), प्रिंटफ का उपयोग करना सबसे अच्छा अभ्यास है।
बजे विलियम टी फ्रॉगार्ड

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
महान उदाहरण - मेरे लिए शुरुआत में हैश धमाके की कुंजी थी
फेलिक्स ईव

22

बाकी के उत्तर बहुत अच्छे हैं, लेकिन अगर कोई व्यक्ति किसी बहु-प्रतिध्वनि को बदलने / अद्यतन करने के लिए समाधान की तलाश में आता है, तो बस कुछ अतिरिक्त जानकारी जोड़ना चाहता है।

इसलिए मैं आप सभी के साथ एक उदाहरण साझा करना चाहता हूं। निम्नलिखित स्क्रिप्ट को एक 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

मेरे पसंदीदा तरीके को नींद को 50 कहा जाता है। यहां iप्रतिध्वनि बयानों के अंदर चर का उपयोग करने की आवश्यकता है।

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

यह अच्छा है, लेकिन कर्सर पहले चरित्र को अस्पष्ट करता है। मुझे लगता है कि प्रतिध्वनि में कुछ रिक्त स्थान आसपास मिल सकते हैं।
मैराथन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.