2011-04-29 60 views
3

我想最後一個部分,因爲從可能的巨大的日誌文件(> 50..1000mb)給定的時間戳「T0」:awk的一個巨大的日誌文件從後面直到時間戳

 __________________ 
    |1 xxx xxx ...  | 
    |2 xxx ...   |  uninteresting part 
    |4 ...    | 
    |...    | 
___|423 ...   | ___ timestamp t0 
    |425 xxx ...  | 
    |437 ...   | 
    |...    |  <-- i want this part (from t0 to EOF) 
    |__________________| 

和一個額外的約束我想用簡單的bash命令來做到這一點。一個簡單的解決方案可能是:

awk '$1 > 423' file.log 

但這掃描整個文件與所有unintresting線。有命令尾部但我只能給他我想要的最後幾行的數量,我不知道 - 我只知道時間戳。有沒有辦法從後面「醒來」,並在第一個時間戳不匹配時停止處理?

回答

4

TAC是你的朋友在這裏:

tac file.log | awk '{ if ($1 >= 423) print; else exit; }' | tac 

TAC將轉儲開始最後一行文件的每一行,然後工作到文件的開頭。做一次就可以得到你想要的線路,然後再次修復它們的順序。

+0

完美!與上面簡單的awk解決方案相比,這可以將處理時間**降低到低於5%**。 thx你:) – kraiz 2011-05-03 12:03:14

0

你可以投票直到你點擊「423」。只是一個假設的例子(未測試)

n=100 # number of lines you want to go back 
while true 
do 
    if tail -$n file | grep -q "423" ;then 
    tail -$n file | awk '$1>423' 
    break 
    else 
    ((n+=100)) # increment every 100 lines 
    fi 
done 
+0

隨着尾巴長度的增長,它具有二次曲線行爲,我想。 – 2011-04-29 14:04:53

+0

我也想。移動而不是擴大尾巴 - 「窗口」會更好。 – kraiz 2011-05-03 12:22:49

1

如果我理解正確的,你只需要從一個時間戳正則表達式到文件的末尾得到n行。

免得說你巨大的文件是這樣的:

~$ cat > file << EOF 
rubish 
n lines of rubish 
more rubish 
timestamp regexp 
interesting 
n interesting lines 
interesting 
end of file 
EOF 

如果你能得到你正在尋找的時間戳一個可行的正則表達式,你可以得到你想要的sed部分:

~$ sed -n '/timestamp regexp/,$ {p}' file 
timestamp regexp 
interesting 
n interesting lines 
interesting 
end of file 
1

使用標準的Unix命令,除了掃描整個文件外,沒有什麼可以做的了。如果你編寫自己的程序,你可以做的文件二進制搜索:

  • 尋求在文件中的一個點,
  • 向前讀取記錄的下一個開始,
  • 檢查是否時間戳太大或太小,
  • 並迭代,直到找到文件中的正確點。

如果時間標記是純數字,您甚至可以使用線性插值而不是純二分搜索進行搜索;如果郵票更復雜,它可能不值得額外編碼,但這取決於你多久需要這些。

事實上,除非你打算做很多事情,並且可以證明性能是一個問題,否則我會採用簡單的awk解決方案。