在bash中使用Unix脚本来搜索日志并返回特定日志文件的特定部分

时间:2015-08-31 07:50:37

标签: bash scripting redhat

我敢说,我主要是一个Windows用户(请不要过早地把我击倒),虽然我过去曾在Linux上玩过(主要是命令行)。 我有一个过程,我必须经历一段时间,它实质上是在目录(和子目录)中搜索某个文件名的所有日志文件,然后从所述日志文件中获取一些东西。

我的第一步是

grep -Ril <filename or Partial filename you are looking for> log/*.log

从那里我有日志文件名和我vi来查找它发生的位置。 澄清一下:grep正在浏览所有日志文件,看看-Ril之后的文件名是否在其中。

vi log/<log filename>
/<filename or Partial filename you are looking for>

j几次找到CDATA,然后我有一个我需要提取的网址,然后在putty做一个选择,复制并粘贴到浏览器中。 然后我退出vi而不保存。

FRED1 triggered at Mon Aug 31 14:09:31 NZST 2015 with incoming file /u03/incoming/fred/Fred.2
Fred.2
start grep
end grep
Renamed to Fred.2.20150831140931

    <?xml version="1.0" encoding="UTF-8"?>
    <runResponse><runReturn><item><name>runId</name><value>1703775</value></item><item><name>runHistoryId</name><value>1703775</value></item><item><name>runReportUrl</name><value>https://<Servername>:<port and path>b1a&amp;sp=l0&amp;sp=l1703775&amp;sp=l1703775</value></item><item><name>displayRunReportUrl</name><value><![CDATA[https://<Servername>:<port and path2>&sp=l1703775&sp=l1703775]]></value></item><item><name>runStartTime</name><value>08/31/15 14:09</value></item><item><name>flowResponse</name><value></value></item><item><name>flowResult</name><value></value></item><item><name>flowReturnCode</name><value>Not a Return</value></item></runReturn></runResponse>
    filePath=/u03/incoming/fred&fileName=Fred.2.20150831140931&team=dps&direction=incoming&size=31108&time=Aug 31 14:09&fts=nzlssftsd01

----------------------------------------------------------------------------------------
FRED1 triggered at Mon Aug 31 14:09:31 NZST 2015 with incoming file /u03/incoming/fred/Fred.3
Fred.3
start grep
end grep
Renamed to Fred.3.20150999999999

    <?xml version="1.0" encoding="UTF-8"?>
    <runResponse><runReturn><item><name>runId</name><value>1703775</value></item><item><name>runHistoryId</name><value>1703775</value></item><item><name>runReportUrl</name><value>https://<Servername>:<port and path>b1a&amp;sp=l0&amp;sp=l999999&amp;sp=l9999999</value></item><item><name>displayRunReportUrl</name><value><![CDATA[https://<Servername>:<port and path2>&sp=l999999&sp=l999999]]></value></item><item><name>runStartTime</name><value>08/31/15 14:09</value></item><item><name>flowResponse</name><value></value></item><item><name>flowResult</name><value></value></item><item><name>flowReturnCode</name><value>Not a Return</value></item></runReturn></runResponse>
    filePath=/u03/incoming/fred&fileName=Fred.3.20150999999999&team=dps&direction=incoming&size=31108&time=Aug 31 14:09&fts=nzlssftsd01

我想要抓取的是CDATA[https://<Servername>:<port and path2>&sp=l999999&sp=l999999]Fred.3.20150999999999 Renamed to Fred.3.20150999999999所指示的网址。

这可能吗? (我对XML格式表示道歉,但它与日志文件中的格式完全相同。)

提前致谢,
电话

2 个答案:

答案 0 :(得分:1)

sed -n 's@\(.*CDATA\[\)\(.*\)\(\]\].*\)@\2@p'  <logfile>

-n禁止自动打印图案空间

@ - as sed pattern delimiter

() - 对模式进行分组

\ 2 - 第二种模式

p - print

**更新 - grep文件模式**

grep -Ril <filename or Partial filename you are looking for> log/*.log | xargs sed -n "/<pattern>/,/filePath=/p" | sed -n 's@\(.*CDATA\[\)\(.*\)\(\]\].*\)@\2@p'

xargs将上一个命令的输出作为输入文件。

如果模式是Fred.3.20150999999999,则第一个sed将从匹配模式打印到filePath =,然后sed将提取CDATA。

答案 1 :(得分:0)

虽然可以使用grep命令来查找文件,但find命令更灵活,更合适一些。查找日志文件的基本用法类似于:

find /path/to/logdir -type f -name "partial*.log"

将在/path/to/logdir下以递归方式搜索名称与模式-type f匹配的文件"partial*.log"

隔离网址可能与其他答案类似,但在此处使用多个表达式,您可以将网址隔离:

sed -e 's/^.*CDATA\[\(http[^]]*\).*$/\1/' <logfilename> \
    -e '/^$/'d \
    -e '/^[ \t\n].*$/'d

输出:

https://<Servername>:<port and path2>&sp=l1703775&sp=l1703775

如果第一个表达式将url本身与<logfilename>内部隔离,则第二个表达式会抑制任何空行,最后是第三个表达式,它会删除以[space,tab或newline]开头返回的片段。< / p>

如果您可以调整find命令以可靠地返回需要从中检索网址的确切文件,那么您可以将findsed命令一起编写为:

sed -e 's/^.*CDATA\[\(http[^]]*\).*$/\1/' \
    $(find /path/to/logdir -type f -name "partial*.log") \
    -e '/^$/'d \
    -e '/^[ \t\n].*$/'d

您只需使用命令替换<logfilename>替换为find中的$(...)命令。

注意有许多不同的方式来编写sed替换,有些可能比这个更优雅,但这就是sed的力量所在。试一试,如果遇到问题请告诉我。我希望这会有所帮助。