Grep

在閱讀日誌時讀取另一個文件以排除單詞的智能方法

  • December 10, 2019

我想要一個單獨的文本文件,我可以隨時修改它,以便在 grepping 日誌文件時排除單詞。到目前為止,我已經寫了下面的基本腳本來達到我的目的。在 SunOS 中。請幫忙。

find /export/home/testing/ -type f -name "apache_logs.txt" |while read file
 do  
   result=$(tail -50 $file |grep -v 'HTTP/1.1" 200'  $file)
   echo "$result" > result1.txt
   grep -v 'akamai/sureroute' | grep -v '/wp7/wp-login.php' | grep -v  'HTTP/1.0" 200' result1.txt  > result.txt; 
 done

在 Solaris 上使用/usr/xpg4/bin/grep能夠從文件中讀取模式-f並使用-F, 然後進行字元串比較,

find /export/home/testing -type f -name apache_logs.txt -exec tail -n 50 {} \; |
/usr/xpg4/bin/grep -vF -f avoid.txt >result.txt

avoid.txt每行都有一個字元串的文本文件在哪裡:

akamai/sureroute
/wp7/wp-login.php
HTTP/1.0" 200
HTTP/1.1" 200

apache_logs.txt這將查找在目錄中或目錄下呼叫的正常文件/export/home/testing。對於每個這樣的文件,tail -n 50呼叫以獲取最後 50 行(根據您的程式碼;使用cat代替tail -n 50來獲取每個文件的全部內容)。

生成的文本行將通過管道/usr/xpg4/bin/grep過濾掉(刪除)包含文件中列出的任何子字元串的每一行avoid.txt

使用的選項grep

  • -v反轉匹配的意義(返回與模式匹配的行)。
  • -F將每個模式視為字元串並進行字元串比較而不是正則表達式匹配。這允許文件中的模式包含在正則表達式中可能是特殊的字元,而不會轉義它們。
  • -f avoid.txt從文件中讀取模式avoid.txt

剩餘的文本行寫入result.txt.

如果沒有該-F選項,您將不得不對其中的模式有點小心,avoid.txt並使它們成為正確的正則表達式。也許像

akamai/sureroute
/wp7/wp-login\.php
HTTP/1\.[01]" 200

如果您只希望find找到一個文件,那麼程式碼可以簡化為

tail -n 50 /path/to/apache_logs.txt |
/usr/xpg4/bin/grep -vF -f avoid.txt >result.txt

您的程式碼存在一些問題:

  • 你不引用變數擴展。請參閱何時需要雙引號?
  • 您不必要地將管道的結果儲存在變數中,然後用於echo將結果輸出到文件。
  • 您的第一個tail+grep管道在管道$file的兩側使用。這將導致grep忽略來自 的輸入tail
  • 您的第二個(更長的)管道將result1.txt僅用於 last grep,並且較早的grep命令將等待從標準輸入讀取數據(將沒有),並最終在 lastgrep完成時被殺死。

這種類型的管道通常看起來像

command inputfile | command | command | command

即,您從一個從某個輸入文件讀取數據並寫入標準輸出的命令開始。輸出由下一個命令讀取,輸出由下一個命令讀取,依此類推。

  • 對於每個找到的文件,輸出文件result.txt都會從頭開始重寫apache_logs.txt,因為您使用>循環對其進行寫入。如果您只希望find找到單個文件,這可能沒問題(在這種情況下,最好不要使用find,因為該文件可能不會在文件系統中移動)。
  • 您使用 . 解析find(找到的文件的路徑名)的輸出read。這通常是一個壞主意,因為 Unix 上的路徑名可能包含任何字元,包括換行符和反斜杠,但 nul 字元 ( \0) 除外,它是 C 程式語言中的字元串終止符。請參閱為什麼循環查找的輸出是不好的做法?

還有相關的:

引用自:https://unix.stackexchange.com/questions/531739