bash 中的 Unix 脚本用于搜索日志和 return 特定日志文件的特定部分

Unix scripting in bash to search logs and return a specific part of a specific log file

敢说,我主要是一个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,然后我有一个 URL 我需要提取,然后在 putty 做一个 select,将其复制并粘贴到浏览器中。 然后我不保存就退出了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] 中的 URL for Fred.3.20150999999999 由行 Renamed to Fred.3.20150999999999.

指示

这可能吗? (对于 XML 格式,我深表歉意,但它与日志文件中的完全一样。)

提前致谢,
电话

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

-n 抑制模式的自动打印space

@ - 作为 sed 模式分隔符

( ) - 对模式进行分组

\2 - 第二个模式

p - 打印

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

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

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

如果模式是 Fred.3.20150999999999,首先 sed 将从匹配的模式打印到 filePath=,然后下一个 sed 将在其中提取 CDATA。

虽然您的 grep 命令可用于定位文件,但 find 命令更灵活,也更合适。定位日志文件的基本用法类似于:

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

它将在 /path/to/logdir 下递归搜索名称与模式 "partial*.log".

匹配的文件 -type f

隔离 url 可以类似于其他答案,但这里使用多个表达式,您可以隔离 url 与:

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

输出:

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

第一个表达式将 url 本身与您的 <logfilename> 隔离开来,第二个表达式抑制任何空行,最后是第三个表达式,它删除 returned 开头的片段使用 [space、制表符或换行符。

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

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

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

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