【问题标题】:bash script to get the spent time from a filebash脚本从文件中获取花费的时间
【发布时间】:2017-10-24 21:47:09
【问题描述】:

我有一个显示脚本之间切换时间的日志文件:

Tue Oct 24 11:57:54 IRST 2017 Script switched from abc to XYZ 
Tue Oct 24 14:03:41 IRST 2017 Script switched from XYZ to ZEN 
Tue Oct 24 15:43:16 IRST 2017 Script switched from ZEN to XYZ 
Tue Oct 24 17:07:25 IRST 2017 Script switched from XYZ to ZEN 
Tue Oct 24 18:40:48 IRST 2017 Script switched from ZEN to XLS 
Tue Oct 24 19:52:26 IRST 2017 Script switched from XLS to XYZ 
Tue Oct 24 20:20:30 IRST 2017 Script switched from XYZ to ZEN 
Tue Oct 24 20:36:06 IRST 2017 Script switched from ZEN to XLS 
Tue Oct 24 21:01:03 IRST 2017 Script switched from XLS to XYZ 
Tue Oct 24 21:47:47 IRST 2017 Script switched from XYZ to ZEN

如何使用 bash 获取每个脚本花费的总时间 所以输出显示如下:

abc 2 hours 30 min 40 sec
XYZ 3 hours 23 min 45 sec
zen ...
XLS ...

【问题讨论】:

  • StackOverflow 是一个帮助您完成程序的论坛。你必须先编写自己的程序,然后真正尝试让它工作,一旦你通过一些好的调试遇到了最后的障碍,然后你问你的问题。您仍然需要先自己完成编写程序的第一步。

标签: linux bash time command


【解决方案1】:

假设您有一个名为 test.txt 的日志文件,以下脚本应该可以工作,

#!/bin/bash

dtime=0
sname=""
while read line
do
    _dtime=$(echo "$line" | awk '{print $1,$2,$3,$4}')
    _sname=$(echo "$line" | awk '{print $10}')

   _dtimesec=$(date +%s -d "$_dtime")
   _timediff=$(( _dtimesec - dtime ))
   [ "x$sname" != "x" ] && printf "$sname %d hours %d minutes %d seconds\n" $(($_timediff/3600)) $(($_timediff%3600/60)) $(($_timediff%60))
   dtime=$_dtimesec
   sname=$_sname

done < test.txt

这将产生如下输出:

 ]$ ./test
 abc 2 hours 5 minutes 47 seconds
 XYZ 1 hours 39 minutes 35 seconds
 ZEN 1 hours 24 minutes 9 seconds
 XYZ 1 hours 33 minutes 23 seconds
 ZEN 1 hours 11 minutes 38 seconds
 XLS 0 hours 28 minutes 4 seconds
 XYZ 0 hours 15 minutes 36 seconds
 ZEN 0 hours 24 minutes 57 seconds
 XLS 0 hours 46 minutes 44 seconds

编辑

为了找到每个脚本花费的总时间,这个修改后的脚本应该可以完成这项工作:

   #!/bin/bash

   dtime=0
   sname=""
   namearr=()
   timearr=()
   while read line
   do
       _dtime=$(echo "$line" | awk '{print $1,$2,$3,$4}')
       _sname=$(echo "$line" | awk '{print $10}')
       _dtimesec=$(date +%s -d "$_dtime")
       _timediff=$(( _dtimesec - dtime ))

       _rc=1
       for n in "${!namearr[@]}"
       do
              if [ "${namearr[$n]}" == "$_sname" ]; then
                  export _rc=$?
                  export ind=$n
                  break;
              else
                  export _rc=1
              fi
       done
       if [ $_rc -eq 0 ]; then
       timearr[$ind]=$(( ${timearr[$ind]} + _timediff ))
       else
              if [ $dtime -eq 0 ] && [ "x$sname" == "x" ]; then
                  :
              else
                  namearr+=($_sname)
                  timearr+=($_timediff)
              fi
      fi

       dtime=$_dtimesec
       sname=$_sname

   done < test.txt

   echo "Total time spent by each script:"
   echo
   for i in "${!namearr[@]}"
   do
       _gtime=${timearr[$i]}
       printf "${namearr[$i]} %d hours %d minutes %d seconds\n" $(($_gtime/3600)) $(($_gtime%3600/60)) $(($_gtime%60))
   done

结果:

 $ ./test
 Total time spent by each script:

 XYZ 4 hours 44 minutes 44 seconds
 ZEN 3 hours 28 minutes 34 seconds
 XLS 1 hours 36 minutes 35 seconds

【讨论】:

    【解决方案2】:

    您可以使用以下gawk 程序:

    time_spent.awk

    BEGIN {
        months["Jan"] = "01"
        months["Feb"] = "02"
        months["Mar"] = "03"
        months["Apr"] = "04"
        months["May"] = "05"
        months["Jun"] = "06"
        months["Jul"] = "07"
        months["Aug"] = "08"
        months["Seb"] = "09"
        months["Oct"] = "10"
        months["Nov"] = "11"
        months["Dec"] = "12"
    }
    
    {
        split($4, time, ":")
        # mktime() manual: https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html
        now = mktime($6" "months[$2]" "$3" "time[1]" "time[2]" "time[3])
        prv = $(NF-2)
        cur = $(NF)
        start[cur] = now
        spent[prv]+=start[prv]?now-start[prv]:0
    }
    
    END {
        for(i in spent) {
            printf "%s seconds spent in %s\n", spent[i], i
        }
    }
    

    将它保存到一个文件 time_spent.awk 并像这样执行它:

    gawk -f time_spent.awk input.log
    

    上例的输出:

    5795 seconds spent in XLS
    0 seconds spent in abc
    17084 seconds spent in XYZ
    12514 seconds spent in ZEN
    

    【讨论】:

    • 很好,无论如何要将秒转换为小时:分钟:秒?所以输出变成XYZ: 02:34:25
    • 给了我这个错误:```awk:spend_time: line 32: function mktime never defined ```
    • 没说你需要 GNU awk (gawk) 来运行它
    【解决方案3】:
    #!/usr/bin/env python
    
    import sys
    from time import strptime
    from datetime import datetime
    
    intervals = (
        ('weeks', 604800),  # 60 * 60 * 24 * 7
        ('days', 86400),    # 60 * 60 * 24
        ('hours', 3600),    # 60 * 60
        ('minutes', 60),
        ('seconds', 1),
        )
    
    def display_time(seconds, granularity=2):
        result = []
    
        for name, count in intervals:
            value = seconds // count
            if value:
                seconds -= value * count
                if value == 1:
                    name = name.rstrip('s')
                result.append("{} {}".format(value, name))
        return ' '.join(result[:granularity])
    
    with open(sys.argv[1], "rb") as df:
        lines = df.readlines()
    
    totals = {}
    
    for i in range(len(lines)-1):
        (_,t1,t2,t3,_,t4,_,_,_,_,_,scr) = lines[i].strip().split(' ')
        st = datetime.strptime(' '.join([t1,t2,t3,t4]), "%b %d %H:%M:%S %Y")
        (_,t1,t2,t3,_,t4,_,_,_,_,_,_) = lines[i+1].strip().split(' ')
        et = datetime.strptime(' '.join([t1,t2,t3,t4]), "%b %d %H:%M:%S %Y")
        if scr not in totals:
            totals[scr] = 0
        totals[scr] += (et-st).seconds
    
        print("{} {}".format(scr,display_time((et-st).seconds, 3)))
    
    print("\nTotals:")
    for scr in totals:
        print("{} {}".format(scr,display_time(totals[scr], 3)))
    

    这是输出,假设您的时间在一个名为 logfile 的文件中:

    $ ./times.py logfile
    XYZ 2 hours 5 minutes 47 seconds
    ZEN 1 hour 39 minutes 35 seconds
    XYZ 1 hour 24 minutes 9 seconds
    ZEN 1 hour 33 minutes 23 seconds
    XLS 1 hour 11 minutes 38 seconds
    XYZ 28 minutes 4 seconds
    ZEN 15 minutes 36 seconds
    XLS 24 minutes 57 seconds
    XYZ 46 minutes 44 seconds
    
    Totals:
    XLS 1 hour 36 minutes 35 seconds
    XYZ 4 hours 44 minutes 44 seconds
    ZEN 3 hours 28 minutes 34 seconds
    
    $
    

    注意:我从这里提取了方便的 display_time 函数:Python function to convert seconds into minutes, hours, and days

    【讨论】:

    • 为什么有2组标签?
    • 第一组是什么,第二组是什么?
    • 知道了,它给出了每个花费的单独时间,如何将它们相加并求和?
    猜你喜欢
    • 2018-03-10
    • 1970-01-01
    • 2013-11-06
    • 2015-01-05
    • 1970-01-01
    • 2016-07-25
    • 2011-09-03
    • 1970-01-01
    • 2013-05-07
    相关资源
    最近更新 更多