簡體   English   中英

創建 awk 程序以添加最后一列數據

[英]Creating awk program to add last column of data

我試圖創建一個 awk 程序來添加最后一列數據(用戶連接的時間),同時使格式仍然可讀(小時不超過 24,分鍾不超過 60。)但是第一行 - 它不顯示時間,生病不得不忽略它。

jms68988 pts/0 161.6.5.14 Fri Mar 22 08:41 still logged in
jms68988 pts/4 ip143-84.snl.wku Wed Mar 20 10:15 - 11:14 (00:58)
jms68988 pts/0 161.6.5.14 Wed Mar 20 09:59 - 07:44 (1+21:45)
jms68988 pts/0 161.6.5.14 Wed Mar 20 09:18 - 09:30 (00:11)   
jms68988 pts/3 ip143-84.snl.wku Mon Mar 18 10:18 - 11:13 (00:55)   
jms68988 pts/6 ip143-84.snl.wku Fri Mar 15 10:15 - 11:14 (00:59)
jms68988 pts/6 ip143-84.snl.wku Wed Mar 13 10:16 - 11:13 (00:57)   
jms68988 pts/1 161.6.5.14 Wed Mar 13 10:05 - 07:47 (4+21:41)
jms68988 pts/0 161.6.5.14 Fri Jan 25 12:42 - 07:57 (2+19:14)
jms68988 pts/7 ip143-84.snl.wku Fri Jan 25 10:28 - 11:16 (00:47)
jms68988 pts/0 161.6.5.14 Fri Jan 25 08:33 - 08:35 (00:01)  

你能用awk做這樣的事情嗎?

你可以在awk很多類似的事情 - 有兩個基本方面需要考慮:

  • 記錄選擇;
  • 記錄處理。

第一個(記錄選擇)是通過在每一行上查找特定的正則表達式來完成的,下面的代碼為您的輸入數據選擇最可能的情況,特別是最終字段匹配:

(<days>+<hours>:<minutes>)

其中<days>+是可選的,三個字段都是數字,字段后面有可選的空格。 這會丟棄諸如第一行之類的行,其中最后一個字段in . 顯然,如果您的數據可以采用不同的形式,您將需要對此進行調整。


第二個(記錄處理)涉及計算出每個所選記錄的最后一個字段所代表的實際時間。 您可以通過將字符串分解為三個部分,將它們轉換為一個公共基值(分鍾,每天 1440 分鍾和每小時 60 分鍾),然后在整個選定記錄集上累積該值來實現。


然后,最后,將這些分鍾轉換回天、小時和分鍾,並輸出結果。

這是一個awk腳本prog.awk ,它就是這樣做的:

/\(([0-9]+\+)?[0-9]+:[0-9]+\) *$/ {
    # Split field on ALL puctuation, this puts empty string
    # on either side, so one of:
    #      1        2          3            4          5
    #   <empty> ( <days>  + <hours>   : <minutes> ) <empty>
    #   <empty> ( <hours> : <minutes> ) <empty>
    # Once we know which one it is, we just extract to the
    # correct variables.

    sz = split($NF, tmArray, /[()+:]/)
    if (sz == 5) {
        dd = tmArray[2] + 0
        hh = tmArray[3] + 0
        mm = tmArray[4] + 0
    } else {
        dd = 0
        hh = tmArray[2] + 0
        mm = tmArray[3] + 0
    }

    # Output line for debugging.

    printf "%3dd %3dh %3dm %s\n", dd, hh, mm, $NF

    # Accumulate minutes.

    total += dd * 1440 + hh * 60 + mm
}
END {
    # After all records, convert minutes back to
    # dd/hh/mm and print.

    dd = int(total / 1440)
    left = total % 1440

    hh = int(left / 60)
    mm = left % 60

    printf "=====\n%3dd %3dh %3dm (from %dm)\n", dd, hh, mm, total
}

順便說一句,如果您擔心我對value = something + 0類的代碼的理智,這只是一種強制awk將變量視為數值而不是字符串的方法。

當您在輸入數據prog.input上運行它時,您可以看到結果:

pax> awk -f prog.awk prog.input
  0d   0h  58m (00:58)
  1d  21h  45m (1+21:45)
  0d   0h  11m (00:11)   
  0d   0h  55m (00:55)   
  0d   0h  59m (00:59)
  0d   0h  57m (00:57)   
  4d  21h  41m (4+21:41)
  2d  19h  14m (2+19:14)
  0d   0h  47m (00:47)
  0d   0h   1m (00:01)  
=====
  9d  19h  28m (from 14128m)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM