Grep
在閱讀日誌時讀取另一個文件以排除單詞的智能方法
我想要一個單獨的文本文件,我可以隨時修改它,以便在 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
僅用於 lastgrep
,並且較早的grep
命令將等待從標準輸入讀取數據(將沒有),並最終在 lastgrep
完成時被殺死。這種類型的管道通常看起來像
command inputfile | command | command | command
即,您從一個從某個輸入文件讀取數據並寫入標準輸出的命令開始。輸出由下一個命令讀取,其輸出由下一個命令讀取,依此類推。
- 對於每個找到的文件,輸出文件
result.txt
都會從頭開始重寫apache_logs.txt
,因為您使用>
循環對其進行寫入。如果您只希望find
找到單個文件,這可能沒問題(在這種情況下,最好不要使用find
,因為該文件可能不會在文件系統中移動)。- 您使用 . 解析
find
(找到的文件的路徑名)的輸出read
。這通常是一個壞主意,因為 Unix 上的路徑名可能包含任何字元,包括換行符和反斜杠,但 nul 字元 (\0
) 除外,它是 C 程式語言中的字元串終止符。請參閱為什麼循環查找的輸出是不好的做法?還有相關的: