वास्तविक समय में कमांड द्वारा लाइनों की संख्या को कैसे प्रदर्शित किया जाए?


15

मैं svn exportअपने आवेदन के लिए एक पैगंबर स्क्रिप्ट के हिस्से के रूप में उपयोग कर रहा हूं , और यह इस तरह दिखता है, जैसे कि कई अन्य, किसी भी प्रकार की प्रगति पट्टी नहीं है।

मेरे पास इस समय दो विकल्प हैं:

  • विकल्पों के बिना इसका उपयोग करना, और हजारों लाइनों को प्रिंट करते हुए देखना
  • --quietजब तक यह पूरा नहीं हो जाता, तब तक इसका उपयोग नहीं करना और कुछ भी जब्त नहीं करना।

क्या वास्तविक समय में कमांड द्वारा लाइनों की संख्या को कम से कम दिखाने का एक तरीका है? जैसे कि:

Exporting SVN directory ... 1234 files

और 1234 वास्तविक समय में इस संख्या वृद्धि को देखें ? मैं एक कमांड के आउटपुट को पाइप करने की कल्पना कर सकता हूं जो सिर्फ यही करेगा, लेकिन कौन सा?

जवाबों:


16
yourcommand | { I=0; while read; do printf "$((++I))\r"; done; echo ""; }

या ब्रैकेट सेक्शन को शेल स्क्रिप्ट में रखें। ध्यान दें कि यह केवल तभी काम करता है जब आपका शेल वास्तव में प्रीइंक्रिमेंट ऑपरेटर का समर्थन करता है, जैसे बैश या ksh93 या zsh। अन्यथा आपको वेतन वृद्धि करनी होगी$I और फिर उसे प्रिंट करना होगा (जैसे I=$((I+1));printf...)। इसके अलावा, अगर printfआपके शेल के साथ बिलिन नहीं है (यह करंट बैश वाला बिलिन है), तो आप बेहतर प्रदर्शन के लिए उपयोग कर सकते हैं echo -neया print -nइसके बजाय। आप सिर्फ न्यूलाइन को दबाना चाहते हैं और \ r की व्याख्या एस्केप चरित्र के रूप में की जाती है।


ओह, मैं कभी भी अपने आप को इसके सभी बदसूरत =और `=` मतभेद और विचित्रता के साथ बशस्क्रिप्टिंग सीखने नहीं दूंगा । :) वे इसे अजगर जैसी वाक्य-रचना वाली भाषा से क्यों नहीं बदलेंगे ...
बोरिस बुर्कोव

अरे, मुझे पता है, क्या! आप अपने द्वारा प्रिंट की गई प्रत्येक नई पंक्ति में कैरेज रिटर्न सिंबल जोड़ सकते हैं, और इससे स्क्रीन पर बाढ़ नहीं आएगी, यह पिछली लाइन को अधिलेखित कर देगी।
बोरिस बुर्कोव

यही कारण है कि printfएक के साथ समाप्त होता है \r। और अगर आप करते हैं echo -ne "$I\r"या क्या होता है print -n "$I\r"। :) मैंने printfहालांकि, उपयोग किया , क्योंकि यह एक नई रेखा को अंत में मुद्रित नहीं करने के लिए डिफॉल्ट करता है, इसलिए \rअभी शुरुआत में वापस जाता है। सभी गूंज कार्यान्वयन -eया -nतर्क का समर्थन नहीं करते हैं, दुर्भाग्य से।
dannysauer 19

1
यह pdksh संस्करण के साथ भी काम करता है, जिसे OpenBSD / bin / sh के लिए उपयोग करता है।
19

1
+1, हालांकि बिल्कुल सही होने के लिए आपको बदलना चाहिए readकरने के लिए read -r(अन्यथा एक बैकस्लैश के बाद से एक पंक्ति के अंत में होगा गिनती के साथ गड़बड़)। संयोग से, काम के एक बिट के साथ, यह आउटपुट की नवीनतम रेखा दिखाने के लिए भी अनुकूलित किया जा सकता है, जो कुछ कमांड के लिए उपयोगी हो सकता है।
रुख

7

यह एक मोटा विचार है, लेकिन आप pvकमांड का उपयोग लाइनों की संख्या को गिनने के लिए कर सकते हैं क्योंकि वे स्क्रीन पर जा रहे हैं और इसे प्रदर्शित करते हैं। pvइसके बीच में कई स्विच हैं एक -lस्विच है जो प्रत्येक पंक्ति को गिनता है क्योंकि यह गुजरता है।

उदाहरण

यहाँ मैं अपने SVN आउटपुट से कुछ फ़ाइलों को अनुकरण करने के लिए थोड़ी देर के लूप का उपयोग कर रहा हूं।

$ for i in $(seq 100); do echo "file$i"; sleep 2; done | pv -l -c >/dev/null
   3 0:00:05 [0.99/s ] [      <=>             

यह आउटपुट लाइन को इस तरह अधिलेखित करता रहेगा:

  18 0:00:36 [   0/s ] [                                     <=>                                                                  ]

  24 0:00:47 [0.991/s ] [                                                <=>                                                      ]

मैं pv से अनजान था। सामान सीखने के लिए हुर्रे!
dannysauer

@dannysauer - pv सीखने में कुछ समय बिताने लायक है, यह किसी भी चीज़ को अनुमति देता है जो पाइप के माध्यम से जाती है और प्रदर्शित होती है।
स्लम

मैंने इसे टिप्पणी पढ़ने के बाद स्थापित किया और इसके साथ खेल रहा हूं। लिनक्स का उपयोग करते हुए अठारह साल, और खोज करने के लिए अभी भी हमेशा नया सामान है। :)
dannysauer

0

आप अपनी कमांड को बैकग्राउंड में जॉब के रूप में चला सकते हैं और अपने stdout (और stderr को वैकल्पिक रूप से) को लॉगफ़ाइल में रीडायरेक्ट कर सकते हैं: command > logfile &जहाँ &जॉब का डिज़ाइन होता है (यदि stderr भी, तो &>इसके बजाय कहें> )।

तब आप अपने लॉगफ़ाइल में लाइनों की संख्या की गणना करने के लिए वर्डकाउंट उपयोगिता का उपयोग कर सकते हैं wc -l

एक गतिशील रूप से बदलती लाइन में राज्य के परिवर्तन को दिखाने के लिए, आप कुछ का उपयोग कर सकते हैं while true; do echo -en '\r'; wc -l logfile; sleep 1; done , लेकिन मैं \rपिछली पंक्ति की सामग्री को मारने के लिए गाड़ी वापसी को आकर्षित करने के लिए बाध्य नहीं कर सकता ।

यह प्रश्न देखें, यह लगभग एक डुप्लिकेट है: /programming/2388090/how-to-delete-and-replace-last-line-in-the-terminal-use-bash


1
लेकिन वह वास्तविक समय का प्रदर्शन चाहता है जो वेतन वृद्धि करता रहता है, जो कि wc नहीं करता है।
कुर्टम

@ कर्टम एह, जो वह बहुत अधिक चाहता है वह नहीं है कि उसकी स्क्रीन printf/print/echoको डैनी द्वारा सुझाए गए परिणामों के साथ बाढ़ आ जाए । :) बेशक, वह उपयोग कर सकता था less, लेकिन मुझे लगता है, वह wc -l logfileहर बार कह सकता है कि वह अधीर हो जाता है। मुझे लगता है, ncursesस्क्रीन के साथ खेलना या साफ़ करना यहाँ ओवरकिल है।
बोरिस बुर्कोव

सही है। वह नहीं चाहता कि यह बाढ़ आए, लेकिन वह प्रगति जानना चाहता है, अन्यथा वह सिर्फ --quiet का उपयोग कर सकता था।
कुर्टम

@kurtm अपडेट देखें: क्या आप मेरी echo -e 'r'कमांड को डीबग करने में मदद कर सकते हैं ? इसे लाइन की पहले से मुद्रित सामग्री को मिटा देना चाहिए, ताकि यह गतिशील रूप से बदल जाए, लेकिन मैं इसे करने के लिए मजबूर नहीं कर सकता :(
बोरिस बुर्कोव

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