按给定模式查找文件,使用grep查找与搜索字符串模式匹配的整个单词计数,忽略某些模式并打印文件名

时间:2017-12-10 10:44:06

标签: regex bash unix awk grep

要求:我需要搜索与“ xceptions ”匹配的整个单词,并计算单个单词出现次数并在找到它的位置打印文件名,也会忽略存在“ throws ”字符串的行,但不会忽略用于搜索行的打印日期模式。

我只能使用' find,grep,zgrep,awk,cut '命令

示例:文件名“server.log”,其中包含不同日期的下方文字。

2017-12-08 00:39:44,453 Some lengthier string.with.javaExceptionString with more data here
2017-12-08 00:39:44,453 Some lengthier string.with.javaExceptionString with more data here
2017-12-09 00:39:44,453 Some more string.with.ContextServiceException some thing here
2017-12-09 00:40:44,453 Some more string.with.ContextServiceException junk values
2017-12-09 00:39:44,453 Some more java.net.MalformedURLException with more data here
2017-12-09 00:39:44,453 function () throws genericException which should not be grepped
2017-12-10 11:11:12,123 function () throws MalformedURLException which should not be grepped
2017-12-10 09:09:12,123 function () throws ContextServiceException which should not be grepped
2017-12-10 09:09:12,123 some oracle error ORA-10001 not grepped
2017-12-09 09:09:12,123 some oracle error ORA-99999 should be counted
2017-12-09 09:09:12,123 another oracle error ORA-20002 with java error ArrayOutOfBoundException and more...
2017-12-09 09:09:12,123 java error ArrayOutOfBoundException and another oracle error ORA-20002  and more...
2017-12-09 09:09:12,123 multiple errors line IOException and NullPointerException, RunTimeException and many more

示例命令打印除日期匹配之外的所有字数:

find /tmp/ -name "*log*" -exec zgrep -HPo "(\b\w*xception|ORA-\w*\b)" {} + 2>/dev/null | sort | uniq -c

当前输出

2 /tmp/server.log:ArrayOutOfBoundException
3 /tmp/server.log:ContextServiceException
1 /tmp/server.log:IOException
2 /tmp/server.log:MalformedURLException
1 /tmp/server.log:NullPointerException
1 /tmp/server.log:ORA-10001
2 /tmp/server.log:ORA-20002
1 /tmp/server.log:ORA-99999
1 /tmp/server.log:RunTimeException
1 /tmp/server.log:genericException
2 /tmp/server.log:javaExceptionString

如果我仅在2017-12-09过滤(需要命令),需要你的帮助,使用'find,grep,awk,cut'在unix中编写单行命令,但不要使用perl或sed预期输出

预期输出仅过滤 2017-12-09 日志并忽略“抛出”的行

2 /tmp/server.log:ArrayOutOfBoundException
2 /tmp/server.log:ContextServiceException
1 /tmp/server.log:IOException
1 /tmp/server.log:MalformedURLException
1 /tmp/server.log:NullPointerException
2 /tmp/server.log:ORA-20002
1 /tmp/server.log:ORA-99999
1 /tmp/server.log:RunTimeException
使用

zgrep ,这样如果有任何gzip文件,它也需要在这些文件中搜索。

1 个答案:

答案 0 :(得分:1)

如果我理解正确, 你正在寻找两个做出两个改变:

  • 排除包含" throws"
  • 的行
  • 排除不以" 2017-12-09"
  • 开头的行

您可以使用zgrep来匹配您想要的行(以" 2017-12-09&#34开头;并包含" xception"), 然后awk排除你不想要的行(包含" throws"), 并排除您不想要的部分行(文件名和例外名称之间的文本):

find ... -exec zgrep -HE '^2017-12-09.*(xception|ORA-)' {} + \
| awk '!/throws/ { print gensub(/^([^:]+:).*\<(\w+xception\w*|ORA-\w+).*/, "\\1\\2", $0) }' \
| sort | uniq -c

这应该适用于awk的GNU实现。

在您进一步澄清之后, 你想要这样一句话:

/tmp/server.log:2017-12-09 09:09:12,123 another oracle error ORA-20002 with java error ArrayOutOfBoundException and more...

对于这样的行:

/tmp/server.log:ORA-20002
/tmp/server.log:ArrayOutOfBoundException

可以使用awk match函数的不同工具, 返回匹配的起始位置,当没有更多匹配时返回0。我们可以使用适当修改的参数重复调用它,只要有匹配项,并在我们开始时打印输出:

find ... -exec zgrep -HE '^2017-12-09.*(xception|ORA-)' {} + \
| awk -F: '!/throws/ { s = $0; while (match(s, /\w+xception\w*|ORA-\w+/)) { print $1 ":" substr(s, RSTART, RLENGTH); s = substr(s, RSTART + RLENGTH + 1); }}' \
| sort | uniq -c