events<xyz>.log
的内容:
<log>
<time>09:00:30</time>
<entry1>abcd</entry1>
<entry2>abcd</entry2>
<id>john</id>
</log>
<log>
<time>09:00:35</time>
<entry1>abcd</entry1>
<entry2>abcd</entry2>
<id>steve</id>
</log>
<log>
<time>09:00:40</time>
<entry1>abcd</entry1>
<entry2>abcd</entry2>
<id>john</id>
</log>
我想将<log>
'john'的所有<id>
条目的entry1和entry2标记提取到一个文件中。我想在shell脚本中执行此操作,该脚本将查看目录中的所有* .log文件。输出应类似于以下内容。
a.out的内容:
<time>09:00:30</time>
<entry1>abcd</entry1>
<entry2>abcd</entry2>
<time>09:00:40</time>
<entry1>abcd</entry1>
<entry2>abcd</entry2>
我是shell脚本的新手,但我尝试使用一些基本命令来至少查看日志:
$ grep -B 3 -in '<id>john</id>' * > /tmp/a.out
上面的命令为我输出了john id标签以上3行,如下所示
...
events111.log-100- <time>09:00:40</time>
events111.log-101- <entry1>abcd</entry1>
events111.log-102- <entry2>abcd</entry2>
events111.log-103- <id>john</id>
....
events112.log-200- <time>06:56:03</time>
events112.log-201- <entry1>abcd</entry1>
events112.log-202- <entry2>abcd</entry2>
events112.log-203- <id>john</id>
这很好,但问题是-3行不会每次都有效,中间可能会有更多的标签,因此需要一些解析逻辑来查找<time>
到{{1}的文本}}
我非常感谢为此制定脚本的一些帮助。
谢谢!
答案 0 :(得分:2)
使用shell脚本执行此操作并不是该作业的正确工具。你真的需要一个解析器。这是python中单个文件的一个。您可以围绕此循环并执行整个日志文件目录。
#!/usr/bin/env python
import sys
from BeautifulSoup import BeautifulSoup, Tag
f = open(sys.argv[1], 'r')
soup = BeautifulSoup(f.read())
for log in soup.findAll('log'):
if log.id.contents[0] == "john":
print log.entry1
print log.entry2
答案 1 :(得分:2)
您是否考虑过使用像xml starlet这样的xml
点击工具来挑选这些日志文件中的各个部分?它会更清洁。
答案 2 :(得分:0)
has() { echo "$line" | grep "$1" >/dev/null; }
while read line; do
has /log && echo;
(has time || has entry1 || has entry2) && echo "$line";
done;
打印
<time>09:00:30</time>
<entry1>abcd</entry1>
<entry2>abcd</entry2>
<log> <time>09:00:35</time>
<entry1>abcd</entry1>
<entry2>abcd</entry2>
<time>09:00:40</time>
<entry1>abcd</entry1>
<entry2>abcd</entry2>
您可能希望也可能不想在“时间”行中取消“<log>
”。
答案 3 :(得分:0)