วิธีการรวมเวลาโดยใช้ทุบตี?


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" +%sให้ 214 วินาที


ดูเหมือนแฮ็ค -y เล็กน้อย แต่เดี๋ยวก่อนมันทำงานในวิธีที่น่าสนใจ
hjk

4

สมมติว่าคุณกำลังใช้ 'เวลา' export TIMEFORMAT=%0Rทุบตีในตัวคำสั่งก่อนที่คุณจะเรียกใช้โปรแกรมของคุณคุณสามารถ เอาต์พุตนั้นจะสามารถเพิ่มได้ภายในไม่กี่วินาทีโดย awk ข้อมูลเพิ่มเติมมีอยู่ในส่วน 'ตัวแปรเชลล์' ของหน้า bash man


4

หากคุณไม่สามารถ (หรือไม่ต้องการ) ใช้TIMEFORMATเพียงแค่ต้องการโอนเวลาเป็นวินาทีให้เพิ่มเข้าด้วยกัน ตัวอย่างเช่นการส่งออกท่อผ่าน:

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

หรือหากคุณต้องการสามารถแลกเปลี่ยนechoคำสั่งสุดท้ายโดย

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

นาทีควรที่จะ$[sum/60%60]ตัดชั่วโมงปิด
Jesse Chisholm

3

ปรับปรุง:

นี่คือการใช้งานใหม่ที่ใช้ประโยชน์จากdc"ฐานการส่งออก" โปรดทราบว่าหากผลรวมทั้งหมดมากกว่า 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:

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

ฉันจะไปกับ Awk และtrเพราะมันง่ายกว่า คำสั่งด้านบนอย่างใดอย่างหนึ่งสร้างเอาต์พุตใหม่ทั้งหมดในรูปแบบต่อไปนี้ (ฉันใช้ข้อความตัวอย่างของตัวเองเพราะฉันคิดว่ามันน่าสนใจมากกว่านี้มีเวลารวมอยู่ด้วยคุณจะทำงานได้ดี)

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

ให้เวลาในรูปแบบข้างต้นเรียกใช้ผ่านสคริปต์ Sed ต่อไปนี้และไพพ์ผลลัพธ์ลง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 ยังรองรับ strftime แต่จะใช้เขตเวลาปัจจุบันของคุณดังนั้นผลลัพธ์จะสับสน


คุณสามารถโทรหาgawkด้วยTZ=UTC0 gawk...ที่จะเอาปัญหาเขตเวลา
Stéphane Chazelas


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 เพื่อให้มันแตก

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