智能方式读取另一个文件以在读取日志时排除单词

智能方式读取另一个文件以在读取日志时排除单词

我想要一个单独的文本文件,我可以随时修改该文件,以便在 grep 日志文件时排除要排除的单词。到目前为止,我已经编写了下面的基本脚本来满足我的目的。在Sun操作系统中。请帮忙。

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

答案1

在 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仅用于最后一个grep,并且较早的grep命令将等待从标准输入读取数据(不会有),并最终在最后一个grep完成后被终止。

    这种类型的管道通常看起来像

    command inputfile | command | command | command
    

    即,您从一个命令开始,该命令从某个输入文件读取数据并写入标准输出。输出由下一个命令读取,并且它是输出由下一个读取,依此类推。

  • 输出文件 ,result.txt重写对于每个找到的文件,从头开始,因为您在循环中apache_logs.txt使用它来写入它。>如果您只希望find找到单个文件,这可能没问题(在这种情况下,最好不要使用,find因为该文件可能不会在文件系统中移动)。

  • find您使用 解析(找到的文件的路径名)的输出read。这通常是一个坏主意,因为 Unix 上的路径名可能包含任何字符,包括换行符和反斜杠,但 nul 字符 ( ) 除外,\0它是 C 编程语言中的字符串终止符。看为什么循环查找的输出是不好的做法?

还相关:

相关内容