Сценарий оболочки для извлечения определенных полей из файлов XML - PullRequest
1 голос
/ 26 июня 2009

Я новичок в оболочке Linux и не могу понять регулярные выражения.

Вот мой вопрос: У меня есть каталог с именем /var/visitors и в этом каталоге у меня есть каталоги типа a, b, c, d. В каждом из этих каталогов есть файл с именем list.xml а вот, например, содержание list.xml из /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

Вот то, что я, как далеко я получил:

cd /var/visitors
find -name "list.xml" | xargs grep ?????

Пожалуйста, помогите.

Ответы [ 5 ]

2 голосов
/ 29 июня 2009

Не элегантно, но это будет работать:

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'

В основном это делает:

  • удалить все новые строки
  • поместите каждую пару значений ключа в отдельную строку
  • добавить: разделитель
  • удалить все содержимое элемента (между <и>)
  • сохранить только поля имени и идентификатора (пропустить все остальные)
  • добавить --- разделитель

Пример вывода:

---
Name: Greg
ID: 52
---
Name: Amy
ID: 53
---
Name: Mr Jones
ID: 51
0 голосов
/ 25 января 2016

Я не включил разделительную линию, потому что я не был уверен, хотите ли вы этого или это просто артефакт использования 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 }
0 голосов
/ 26 июня 2009

Это очень грязно, но если вы уверены, что они в том формате, в котором они находятся, вы можете собрать немного perl вместе, чтобы разобрать его ... что-то вроде

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

это может быть не идеально, но близко к выполнению того, что вы ищете. Я уверен, что, возможно, есть какой-то Perl-модуль, который будет анализировать и XML для вас, но для такой несложной схемы, я думаю, вы без нее обойдетесь.

0 голосов
/ 29 июня 2009

Предполагается, что у вас есть файл 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

Если это не совсем то, что вам нужно, подгоните его, чтобы соответствовать вашим конкретным требованиям.

0 голосов
/ 26 июня 2009

Grep здесь не поможет, вам нужно использовать что-то вроде sed или awk.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...