हर नई लाइन के सामने एक टेक्स्ट रखें, जो प्रोग्राम को स्टडआउट करने के लिए प्रिंट करता है


9

इसलिए मैं कुछ लॉगिंग और उसके बाद करना चाहता हूं, एक बैश स्क्रिप्ट के आउटपुट के सामने एक तारीख डालना चाहता हूं। समस्या यह है कि आउटपुट की कई लाइनें हैं। मैं पूरे आउटपुट से पहले केवल तारीख डाल सकता हूं। लेकिन फिर मेरे पास लॉग्स में तारीख के बिना एक पंक्ति है। बेशक, मैं मान सकता हूं कि उपरोक्त पंक्ति से तारीख समान है, लेकिन मुझे उम्मीद थी कि एक समाधान है। अग्रिम में धन्यवाद!

यह मेरी स्क्रिप्ट है जो किसी अन्य स्क्रिप्ट को कॉल करती है:

#!/bin/sh
echo $(date "+%F %T") : starting script
echo $(date "+%F %T") : $(./script.sh)
echo $(date "+%F %T") :script ended

यह आउटपुट है:

2012-07-26 15:34:12 : starting script
2012-07-26 15:35:14 : First line of output
second line of output
2012-07-26 15:35:17 : script ended

और जो मैं करना चाहता हूं, वह है:

2012-07-26 15:34:12 : starting script
2012-07-26 15:35:14 : First line of output
2012-07-26 15:35:15 : second line of output
2012-07-26 15:35:17 : script ended

मुझे नहीं लगता कि आप सिर्फ दूसरी स्क्रिप्ट बदल सकते हैं?
जमैट

नहीं, दुर्भाग्य से नहीं। इसलिए मैं यहां आया हूं।
tzippy

2
संबंधित: stackoverflow.com/questions/21564/… इसके अलावा: stackoverflow.com/a/1508098/259953
Der Hochstapler

जवाबों:


9

स्टैक ओवरफ्लो पर एक समान प्रश्न के अनुसार , 2 महान विकल्प हैं।

awk ( उत्तर )

<command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; }'

एनोटेट ( उत्तर )

एनोटेट एक छोटी बैश स्क्रिप्ट है, जिसे या तो सीधे यहां दिए गए लिंक के माध्यम से प्राप्त किया जा सकता है, या डेबियन आधारित सिस्टम पर, पैकेज के माध्यम से devscripts(के रूप में annotate-output)।


3

मुझे लगता है कि आप इसके लिए awk का उपयोग कर सकते हैं:

./script.sh | awk '{ print strftime()" : "$0; }'

( strftime द्वारा लौटाए गए दिनांक को प्रारूपित करने के लिए http://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html देखें ())


2
awk: calling undefined function strftime- यह विशिष्ट है gawk?
डैनियल बेक

अब जब आप इसका उल्लेख करते हैं, तो यह प्रतीत होता है: /
फ्लिंटन

2

आप उपयोग कर सकते हैं awk

./script.sh | awk '{ print d,$1}' "d=$(date "+%F %T")"

awkएक इनपुट स्ट्रीम लेता है और आउटपुट को संशोधित करता है। यह स्क्रिप्ट कह रही है "मूल उत्पादन के बाद प्रिंट डी", फिर dतारीख के साथ पॉप्युलेट होता है।


1
क्या यह dateकेवल एक बार अभिव्यक्ति का मूल्यांकन नहीं करता है , ताकि इस तरह की सभी लाइनें एक ही समय में प्रिंट हों?
डैनियल बेक

@ डैनियलबेक हाँ, यह करता है - मैंने मान लिया था कि यह हर बार तारीख उठा रहा था लेकिन अभी जल्दी से अपना परीक्षण पूरा कर लिया है
पॉल

1

यह वर्तमान तिथि और समय को आउटपुट की प्रत्येक पंक्ति से पहले प्रिंट करेगा ./script.sh:

set -f
./script.sh | while read -r LINE; do echo $(date "+%F %T") : "$LINE"; done
set +f

यह काम किस प्रकार करता है

  • set -fबैश विस्तार बंद कर देता है (या echo *एक वास्तविक तारांकन प्रिंट नहीं करेगा)।

  • while read -r LINE; do ... doneचर में आउटपुट की एक पंक्ति को बचाता है $LINEऔर निष्पादित करता है ..., जब तक कि सभी लाइनें संसाधित नहीं होती हैं।

  • इको $ (दिनांक "+% F% T"): "$ LINE" वर्तमान समय और दिनांक के साथ लाइन प्रिंट करता है।

  • set +f बैश विस्तार को फिर से चालू करता है, इसलिए यह आपके बाकी बैश स्क्रिप्ट के साथ हस्तक्षेप नहीं करेगा।


इसका मूल्यांकन केवल एक बार किया जाता है, इसलिए प्रत्येक sedदूसरी स्क्रिप्ट शुरू करने से ठीक पहले, उसी तिथि को सम्मिलित करता है। संभावना नहीं उपयोगकर्ता क्या चाहता है ...
डैनियल बेक

मुझे नहीं लगता कि यह प्रयास भी काम करेगा। AFAIK, पूरे उपधारा को पहले पूरी तरह से मूल्यांकन किया जाता है, फिर लूप का पता लगाया जाता है। तो अब समय निष्पादन के बाद से हैं ।
डैनियल बेक

आपका उदाहरण काम नहीं करता है, क्योंकि आप केवल उत्पादन में देरी करते हैं, निष्पादन नहीं ls। बस निम्नलिखित के साथ अपनी स्क्रिप्ट की कोशिश script.sh: #!/bin/bash(newline)echo 1 ; sleep 1 ; echo 2 ; sleep 2 ; echo 3 ; sleep 3 ; echo 4
डैनियल बेक

लूप के बजाय लूप के readसाथ प्रयोग करें while
शेपनर

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