बैश का उपयोग करने का समय कैसे?


12

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

process1    00:03:34
process2    00:00:35
process3    00:12:34

कुल चलने का समय प्राप्त करने के लिए मैं दूसरा कॉलम कैसे जोड़ सकता हूं? मैं के माध्यम से प्रत्येक पंक्ति pipping कोशिश कर सकते हैं

awk '{sum += $2 } END { print sum }

लेकिन इससे कोई मतलब नहीं है क्योंकि मूल्य प्राकृतिक संख्या नहीं हैं।

जवाबों:


15
#!/bin/sh

EPOCH='jan 1 1970'
sum=0

for i in 00:03:34 00:00:35 00:12:34
do
  sum="$(date -u -d "$EPOCH $i" +%s) + $sum"
done
echo $sum|bc

date -u -d "jan 1 1970" +%sदेता है 0. तो date -u -d "jan 1 1970 00:03:34" +%s214 सेकंड देता है।


थोड़ा हैक-वाई लगता है, लेकिन हे, यह एक दिलचस्प (सॉर्ट-इन) तरीके से काम करता है।
hjk

4

मान लें कि आप अपने प्रोग्राम को चलाने से पहले bash 'time' अंतर्निहित कमांड का उपयोग कर रहे हैं, तो आप कर सकते हैं export TIMEFORMAT=%0R। आउटपुट तब awk द्वारा पूरे सेकंड में जोड़ने योग्य होगा। अधिक जानकारी बैश मैन पेज के 'शेल वेरिएबल्स' सेक्शन में उपलब्ध है।


4

यदि आप (बस नहीं चाहते हैं) TIMEFORMATसेकंड में समय को स्थानांतरित करने की आवश्यकता है, तो इसे एक साथ जोड़ सकते हैं। उदाहरण के लिए पाइप आउटपुट के माध्यम से:

{                                           
sum=0
while IFS="[ :]" proc_name h m s
do
    let sum+=$((60*($m+60*$h)+$s)) 
done 
echo $sum  
} 

या फिर आप पिछले विनिमय कर सकते हैं चाहते हैं, तो echoद्वारा -command

printf "%02d:%02d:%02d\n" $[sum/3600] $[sum/60] $[sum%60]

मिनटों को $[sum/60%60]घंटे बंद करना चाहिए ।
जेसी चिशोल्म

3

अपडेट करें:

यहाँ एक नया कार्यान्वयन है जो dc's' आउटपुट बेस का उपयोग करता है। ध्यान दें कि यदि कुल योग 60 घंटे से अधिक है, तो यह तीन के बजाय चार अंतरिक्ष-पृथक मानों का उत्पादन करेगा । (और यदि कुल योग एक घंटे से कम है, तो केवल दो अंतरिक्ष-पृथक मान आउटपुट होंगे।)

awk '{print $2}' file.txt | tr : \ | dc -f - -e '60o0ddd[+r60*+r60d**+z1<a]dsaxp'

इनपुट को घंटे, मिनट, सेकंड के त्रिभुज में माना जाता है, जैसा कि प्रश्न में दिखाया गया है।

दिए गए इनपुट पर आउटपुट है:

 16 43

मूल उत्तर:

dcअपने डेस्क कैलकुलेटर के साथ ऐसा करते हैं । यह बैक-एंड टू है bc, और यह बेहद लचीला है, हालांकि अक्सर इसे गुप्त माना जाता है।


सबसे पहले, केवल समय देने के लिए कुछ पूर्व-प्रसंस्करण, और कॉलनों को रिक्त स्थान में परिवर्तित करना:

awk '{print $2}' | tr : ' '

हम सिड के साथ भी ऐसा कर सकते हैं:

sed -En -e 's/^.*([0-9][0-9]):([0-9][0-9]):([0-9][0-9]).*$/\1 \2 \3/p'

मैं अवाक के साथ जाऊँगा और trक्योंकि यह सरल है। उपरोक्त कमांड में से कोई भी निम्न प्रारूप में एक साफ आउटपुट उत्पन्न करता है। (मैं अपने स्वयं के उदाहरण पाठ का उपयोग कर रहा हूं क्योंकि मैं इसे और अधिक दिलचस्प मानता हूं; इसमें घंटे शामिल हैं। आपका काम भी यही होगा।)

$ cat input
9 39 42
8 04 50
7 49 32
10 01 54
7 19 18

उपरोक्त प्रारूप में समय को देखते हुए, उन्हें निम्न सेड स्क्रिप्ट के माध्यम से चलाएं और परिणाम dcको दिखाए गए अनुसार पाइप करें :

sed -e '1s/^/0 /' -e 's/$/ r 60 * + r 60 60 * * + +/' -e '$s/$/ 60 60 * ~ 60 ~ f/' input | dc

(बग़ल में स्क्रॉल को कम करने के लिए टूट गया :)

sed <input \
    -e '1s/^/0 /' \
    -e 's/$/ r 60 * + r 60 60 * * + +/' \
    -e '$s/$/ 60 60 * ~ 60 ~ f/' |
      dc 

उस क्रम में आउटपुट सेकंड, मिनट, घंटे होगा। (ध्यान दें कि यह एक उल्टा अनुक्रम है।) मैं अभी सीख रहा हूं dcइसलिए यह एक सही समाधान नहीं है, लेकिन मुझे लगता है कि यह पहली नज़र में बहुत अच्छा है dc

उदाहरण इनपुट और आउटपुट, मेरे टर्मिनल से सीधे चिपकाया गया:

$ cat input 
9 39 42
8 04 50
7 49 32
10 01 54
7 19 18
$ sed -e '1s/^/0 /' -e 's/$/ r 60 * + r 60 60 * * + +/' -e '$s/$/ 60 60 * ~ 60 ~ f/' input | dc 
16
55
42
$ 

2

यहाँ मेरा समाधान है - उपयोग split()। सेकंड में कुल समय मुद्रण:

awk '{
        split($2, tm, ":");
        tottm += tm[3] + tm[2] * 60 + tm[1] * 3600;
    }
    END {
        print tottm;
    }' ptime

अच्छा समय प्रारूप में मुद्रण:

awk '{
        split($2, tm, ":");
        secs += tm[3]; 
        mins += tm[2] + int(secs / 60); 
        hrs += tm[1] + int(mins / 60);
        secs %= 60; mins %= 60;
    }
    END {
        printf "%d:%d:%d\n", hrs, mins, secs;
    }' ptime

GNU awk भी स्ट्रैटिफ़ का समर्थन करता है, लेकिन यह आपके वर्तमान समयक्षेत्र का उपयोग करेगा, इसलिए परिणाम भ्रामक होंगे।


आप कॉल कर सकते हैं gawkके साथ TZ=UTC0 gawk...समय क्षेत्र मुद्दा दूर करने के लिए।
स्टीफन चेज़लस


0

यहाँ विषयों पर विविधता, लेकिन अधिक पाइप

echo """
process1    00:03:34
process2    00:00:35
process3    00:12:34
"""  | \
     sed 's/process.  *\([0-9]\)/\1/g' | \
     xargs -i{} date +%s --date "1970-1-1 {}" | \
     awk '{sum += $1; cnt +=1} 
         END {
               print sum / 60, " total minutes processing";
               print (sum / 3600) / cnt, "minutes per job"
         }'
916.717  total minutes processing
5.09287 minutes per job

0

लगभग कोई भी शेल गणित कर सकता है:

#!/bin/sh

IFS=:; set +f
getseconds(){ echo "$(( ($1*60+$2)*60+$3 ))"; }

for   t in 00:03:34 00:00:35 00:12:34
do    sum=$((sum + $(getseconds $t) ))
done
printf '%s\n' "$sum"

getseconds $=tविभाजित करने के लिए इसे zsh में उपयोग करें ।

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