Shell脚本从XML文件中提取某些字段

时间:2009-06-25 23:32:22

标签: regex linux bash

我是Linux shell的新手,我无法理解正则表达式。

这是我的问题: 我有一个名为/var/visitors的目录 在这个目录下,我有abcd等目录。 在每个目录中,都有一个名为list.xml的文件 例如,这里是来自list.xml的{​​{1}}的内容:

/var/visitors/a

我想要做的是将<key>Name</key> <string>Mr Jones</string> <key>ID</key> <string>51</string> <key>Len</key> <string>53151334</string> 字段与其对应的字符串合并,并将Name字段与其对应的字符串合并。我不需要任何其他领域。

ID

这就是我到底有多远:

Name: Mr Jones
ID: 51
---
Name: Ms Maggie
ID: 502

请帮忙。

5 个答案:

答案 0 :(得分:2)

不优雅,但这样可行:

find -name "list.xml" | xargs cat | tr -d "\n" | sed 's/<\/string>/\n/g' | sed 's/<\/key>/: /g' | sed 's/<[^>]*>//g' | egrep "Name:|ID:" | sed 's/Name: /---\nName: /g'

基本上它是这样做的:

  • 删除所有换行符
  • 将每个键值对放在自己的行上
  • 添加:分隔符
  • 删除所有元素内容(在&lt;和&gt;之间)
  • 仅保存名称和ID字段(删除所有其他字段)
  • 添加---分隔符

示例输出:

---
Name: Greg
ID: 52
---
Name: Amy
ID: 53
---
Name: Mr Jones
ID: 51

答案 1 :(得分:0)

Grep在这里不会帮助你,你需要使用像sed或awk这样的东西。

答案 2 :(得分:0)

这真的很脏,但是如果你确定它们处于它们所处的格式中,你可以抛出一些perl来解析它...类似

for (<STDIN>) {
  if (/<key>([^<]*)</) { print $1 . " : "; }
  if (/<string>([^<]*)</) { print $1 . "\n"; }
}

这可能并不完美,但接近完成你正在寻找的东西。我确信可能还有一些perl模块会为你解析XML,但对于这样一个非复杂的模式,我认为如果没有它,你会没事的。

答案 3 :(得分:0)

假设您的文件foo.bar包含以下文本:

<key>Name</key>
<string>Mr Jones</string>
<key>ID</key>
<string>51</string>
<key>Len</key>
<string>53151334</string>

这样的事情会起作用:

$ awk -F '[<>]' '{if (FNR%2==1) {printf "%s: ",$3} else {print $3}}' foo.bar
Name: Mr Jones
ID: 51
Len: 53151334

如果它不完全符合您的要求,可以进一步满足您的特定要求。

答案 4 :(得分:0)

我没有包含分隔线,因为我不确定您是否需要它,或者它只是使用grep的工件。添加它很容易:

find -name "list.xml" | xargs awk  -F '[<>]' -f xml.awk < in.dat

xml.awk的内容:

$2 != "string" { K=$3 }
$2 == "string" { if ((K == "Name") || (K == "ID")) print K ": " $3 }