2014-07-23 54 views
1

Im新到AWK,並且試圖找出如何獲得所有結果,其中第一列等於變量,日期是大於另一個unix時間戳格式化變量。我使用'last'作爲我的命令。輸出示例如下:

bob  pts/2  172.6.14.37  Fri July 24 12:43 - 12:17 (9+23:34) 
bob  pts/2  172.6.14.37  Fri July 24 10:03 - 12:17 (5+23:34) 
bob  pts/2  172.6.14.37  Tue June 4 17:55 - 09:42 (8+15:46) 
bob  pts/2  172.6.14.37  Tue Mar 4 17:55 - 09:42 (8+15:46) 
tim  pts/1  172.6.14.37  Mon Mar 3 16:22 - 17:30 (1+01:08) 
root pts/1  172.6.14.37  Thu Feb 27 09:38 - 09:56 (4+00:18) 

所以我想要所有結果'bob'在第一列。我有

last -f /var/log/btmp | awk '$1 == "bob"' 

這給了我所有bobs失敗的登錄。現在,我需要重新篩選,其中提交日期大於說「20140723145100」像

last -f /var/log/btmp | awk '$1 == "bob" && $4 >= $DATE' 

假設$ DATE = 20140723145100,結果我想應該是:

bob  pts/2  172.6.14.37  Fri July 24 12:43 - 12:17 (9+23:34) 
bob  pts/2  172.6.14.37  Fri July 24 10:03 - 12:17 (5+23:34) 
+0

這是很笨拙的解析'週四02月27日09:38 - 09:56'在AWK或shell尤其是當'year'解析失蹤。 – anubhava

+0

@anubhava我完全同意。現在我正在努力尋找其他解決方案。 – Kiksy

回答

3

的bash:

user=bob 
since=20140623145100 
last -Fa -f /var/log/btmp | 
while read line; do 
    set -- $line # no quotes here 
    [[ $1 == "$user" ]] || continue 
    [[ $(date -d "$3 $4 $5 $6 $7" +%Y%m%d%H%M%S) > $since ]] && echo "$line" 
done 
+0

我剛剛意識到''$ 3 $ 4 $ 5 $ 6 $ 7''可以寫成''$ {*:3:5}'' –

+0

'd = $(date -d「$ 3 $ 4 $ 5 $ 6 $ 7」+ %Y%米%d%H%M%S); [[$ d ==「$ since」||) $ d>「$ since」]]'。和'[[!! $ d <「$,因爲」]]'在其他情況下仍然有效。或者可能只是'[[$(date -d「$ 3 $ 4 $ 5 $ 6 $ 7」+%Y%m%d%H%M%S)-ge $ since]]'或'(($(date -d「$ 3 $ 4 $ 5 $ 6 $ 7「+%Y%m%d%H%M%S)> = $自))'。 – konsolebox

3

使用-s選項last

last -s 20140723145100 

man last

-s,--since時間

顯示自指定時間登錄的狀態。這是有用的,例如,用於容易地確定在特定時間登錄的人員。 選項通常與--until結合使用。

然後grep的用戶:

last -s 20140723145100 | grep "^bob" 

由於you do not have-s選項,您可以使用此解決方法:存儲所有的last輸出和輸出在一定時間內(使用-t選項)。然後比較輸出:

last -f /var/log/btmp | grep "^bob" > everything 
last -f /var/log/btmp -t "20140723145100" | grep "^bob" > upto_20140723145100 

grep -vf upto_20140723145100 everything 
+0

出於某種原因,我沒有-s選項。這裏是我最後一個'man last'的pastebin。http://pastebin.com/DVFEfugL – Kiksy

+0

如何使用'-t'(到時間),保存輸出並與'last'的正常輸出進行比較? – fedorqui

+0

我希望從現在開始一直到以前的所有事情,所以-t沒有用,可悲。 – Kiksy

3

利用GNU awk中:

gawk -v user=bob -v date=20140723145100 -F '[[:space:]]{3,}| - ' '$1 == user { cmd = "exec date -d \"" $4 "\" +%Y%m%d%H%M%S"; cmd | getline d; close(cmd); if (d >= date) print }' sample 

輸出:

當然
bob  pts/2  172.6.14.37  Fri July 24 12:43 - 12:17 (9+23:34) 
bob  pts/2  172.6.14.37  Fri July 24 10:03 - 12:17 (5+23:34) 

實際命令是last -f /var/log/btmp | gawk -v user=bob -v date=20140723145100 ...

而且這裏有一個腳本版本:

#!/usr/bin/gawk -f 
BEGIN { 
    FS = "[[:space:]]{3,}| - " 
} 
$1 == user { 
    cmd = "exec date -d \"" $4 "\" +%Y%m%d%H%M%S" 
    cmd | getline d 
    close(cmd) 
    if (d >= date) 
     print 
} 

用法:

last -f /var/log/btmp | gawk -v user=bob -v date=20140723145100 -f script.awk 
+2

您發佈了很多很好的答案,但它們很難閱讀(滾動)。嘗試添加一些新行。 –

+0

@glennjackman增加了一個腳本版本。 – konsolebox

+0

謝謝。在單引號內添加換行符也很有效:它可以保持單線性,並且可以安全地切割'n'paste。 –