簡體   English   中英

重擊而非常慢

[英]Bash while VERY slow

我有一個while循環,該循環讀取郵件日志文件並將其放入數組中,這樣我就可以在數組中搜索並匹配/搜索流。 不幸的是,while循環需要很長時間才能遍歷文件,它是一個非常大的文件,但是必須有另一種更快的方式來完成此操作。

cat /home/maillog |grep "Nov 13" |grep "from=<xxxx@xxxx.com>" |awk '{print $6}' > /home/output_1 

while read line; do awk -v line="$line" '$6 ~ line { print $0 }' /home/maillog >> /home/output_2 ; done < /home/output_1

有任何想法嗎? 提前致謝。

讓我們分析您的腳本並嘗試解釋為什么它很慢。

首先,我們對第一行進行微優化。 它不會加快速度,但這僅僅是教育性的。

cat /home/maillog |grep "Nov 13" |grep "from=<xxxx@xxxx.com>" |awk '{print $6}' > /home/output_1 

在這一行中,您對不同的二進制文件進行了4次調用,最后可以一次調用一個二進制文件。 為了提高可讀性,您可以保留此行。 但是,這里有兩個要點:

  1. cat沒用。 cat程序主要用於合並文件。 如果僅添加一個文件,則基本上是多余的。 特別是如果您要將其傳遞給grep

     cat file | grep ... => grep ... file 
  2. 與awk結合使用的多個抓取...可以寫為單個awk

     awk '/Nov 13/ && /from=<xxxx@xxxx.com>/ {print $6}' 

所以整行可以寫成:

awk '/Nov 13/ && /from=<xxxx@xxxx.com>/ {print $6}' /home/maillog > /home/output_1

第二部分是事情變慢的地方:

while read line; do 
   awk -v line="$line" '$6 ~ line { print $0 }' /home/maillog >> /home/output_2 ;
done < /home/output_1

為什么這么慢? 您從/home/output_1表格中讀取的每一行,將awk程序加載到內存中,打開文件/home/maillog ,對其進行處理,然后關閉文件/home/maillog 同時,在處理的每一行中,每次都打開/home/output_2 ,將文件指針置於文件末尾,寫入文件並再次關閉文件。

整個程序實際上可以通過一個awk完成:

awk '(NR==FNR) && /Nov 13/ && /from=<xxxx@xxxx.com>/ {a[$6];next}($6 in a)' /home/maillog /home/maillog > /home/output2

暫無
暫無

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

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