我想要一个单独的文本文件,我可以随时修改该文件,以便在 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 编程语言中的字符串终止符。看为什么循环查找的输出是不好的做法?
还相关: