LINUX.ORG.RU

распарсить xml в bash

 , ,


0

3

Есть файл в котором две группы тегов:

<Vars>
<Var id="numberVar" address="number" name="name" dir="in/out..."/>
...
</Vars/
<Events>
<Event id="numberId" VarId="numberVar" .../>
</Events>
Надо что бы посредством bash в блок Event поле VarId попали номера из Var id. Прошу помощи.

Перемещено mono из talks

★★★★★

Ответ на: комментарий от Deleted

Понимаю твою жопоболь ;) у меня так с Си.

это только в первые 5К строк. Потом привыкнешь.

emulek
()
Ответ на: комментарий от DRVTiny

Тем не менее, типы данных в ограниченном виде присутствуют в BASH:

типы в баше не нужны, это не его ниша.

поясню свою мысль: во первых, обычный массив и ассоциативный массив (а не list и hash) это не типы, а коллекции. Во вторых, тип «строка» (по умолчанию) и «целое» конечно нужны, сами по себе, но не нужно их мешать. Смотри, всего одно преобразование:

$ time ( J=0; while [ $J != 100000 ]; do (( J++ )); done )

real	0m4.840s
user	0m4.832s
sys	0m0.001s
$ time ( J=0; while (( $J != 100000 )); do (( J++ )); done )

real	0m3.193s
user	0m3.188s
sys	0m0.001s
и быстродействие просело на 25%. Т.е. типы-то есть, но если ты решил «это целое», то переводи в строку только если НАДО.

В третьих, ты забыл ещё и local, нужно для рекурсивных функций. Но годно и для инкапсуляции в любых функциях.

emulek
()
Ответ на: комментарий от emulek

local - это же не тип данных, а область видимости. Вообще одинарные квадратные скобки в современном BASH - это моветон. Двойные, насколько я знаю, умеют работать с числами без преобразования.

DRVTiny ★★★★★
()
Последнее исправление: DRVTiny (всего исправлений: 1)
Ответ на: комментарий от DRVTiny

Вообще одинарные квадратные скобки в современном BASH - это моветон

нет. Это метод работы с файлами. например [ -x filename ] истинно тогда, и только тогда, когда файл существует и доступен для выполнения(причём не кем угодно, а тем, кто запустил bash).

Двойные, насколько я знаю, умеют работать с числами без преобразования.

я проверил, действительно одинаково. Но у (( )) есть преимущество в читабельности, и они однозначны(т.е. работают только с цифрами, а вот сколько будет [[ X < Y ]] сказать сложно, не зная, числа это, или строки. И правила приведения мне не известны, это не сишка, с её стандартом.

local - это же не тип данных, а область видимости.

это был мой ответ на declare -g

emulek
()
Последнее исправление: emulek (всего исправлений: 1)
Ответ на: комментарий от emulek

это был мой ответ на declare -g

Это я в качестве примера того, как крут бывает declare, а не показать, что в BASH есть области видимости :)

DRVTiny ★★★★★
()
Ответ на: комментарий от emulek

я проверил, действительно одинаково. Но у (( )) есть преимущество в читабельности

Была тема на LOR'е, я тестировал как раз кавычки.

Получилось «вроде бы даже не быстрее, вроде бы даже медленнее» - при грамотном использовании именно двойные квадратные кавыки оказываются мистически образом быстрее прочих.

DRVTiny ★★★★★
()
Ответ на: комментарий от DRVTiny

[([{это}])] скобки.

при грамотном использовании именно двойные квадратные кавыки оказываются мистически образом быстрее прочих.

естественно. Для строк это то, что нужно. Но они не умеют файлы. И регулярки там черезжопные.

emulek
()
Ответ на: комментарий от splinter

Отчасти да, но зато почти везде есть и если освоить one-liners ключи, можно забить на sed/awk. Плюс пользуюсь для генерации всяких занудных вещей, парсинга, etc. Просто потому что в bash скучно, а python, ruby не всегда бывают.

anonymous
()
Ответ на: комментарий от splinter
#!/bin/bash

awk -F "," -v f1=f1.txt -v f2=f2.txt '
/BOOLEAN/{
  printf "<Var "                              >f1
  printf   "id"        "=\""  $1       "\"\t" >f1
  printf   "address"   "=\""  $1       "\"\t" >f1
  printf   "type"      "=\""  "$type"  "\"\t" >f1
  printf   "desc"      "=\""  $2       "\"\t" >f1
  printf   "localDesc" "=\""           "\"\t" >f1
  printf   "dir"       "=\""  "$dir"   "\"\t" >f1
  printf   "local"     "=\""           "\"\t" >f1
  print  "/>"                                 >f1

  printf "<Event "                            >f2
  printf   "id"        "=\""  $1       "\"\t" >f2
  printf   "VarId"     "=\"" "$VarId"  "\"\t" >f2
  printf   "name"      "=\""  $2       "\"\t" >f2
  printf   "localDesc" "=\""           "\"\t" >f2
  printf   "relay"     "=\""  "false"  "\"\t" >f2
  printf   "type"      "=\""           "\"\t" >f2
  print  "/>"                                 >f2
}
'  file.csv

(
  echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  echo "<HMIConfig05>"
  echo "<Vars>"
  cat f1.txt
  echo "</Vars>"
  echo "<Events>"
  cat f2.txt
  echo "</Events>"
) >1.txt
rm f1.txt f2.txt

и если ничего далее с xml не изменяется, то замени:

  printf   "VarId"     "=\"" "$VarId"  "\"\t" >f2
на:
  printf   "VarId"     "=\"" $1        "\"\t" >f2

anonymous
()
Ответ на: комментарий от anonymous

и дальше:

function item(f, a, b) {
  printf "%s=\"%s\"\t", a, b >f
}
/BOOLEAN/{
  printf "<Var " >f1
  item(f1, "id",        $1)
  item(f1, "address",   $1)
  item(f1, "type",      "$type")
  item(f1, "desc",      $2)
  item(f1, "localDesc")
  item(f1, "dir",       "$dir")
  item(f1, "local")
  print "/>" >f1

  printf "<Event " >f2
  item(f2, "id",        $1)
  item(f2, "VarId",     "$VarId")
  item(f2, "name",      $2)
  item(f2, "localDesc")
  item(f2, "relay",     "false")
  item(f2, "type")
  print "/>" >f2
}

anonymous
()
Ответ на: комментарий от anonymous

спасибо Бро! завтра попробую! от рутины избавляешь.

splinter ★★★★★
() автор топика
Ответ на: комментарий от emulek

Двойные квадратные скобки умеют файлы, как и обычные квадратные: [[ -f $FILE ]] && doSomething, при этом в отличие от одинарных двойные всегда корректно работают с «неокавыченными» переменными, содержащими имя файла или каталога:

> 'a b c'
F='a b c'
[[ -f $HOME/$F ]] && echo 'hello from double ['
[ -f $HOME/$F ] && echo 'hello from single ['

Вывод:

hello from double [
bash: [: too many arguments

Работа с регулярками в BASH вполне полноценная, это обычные extended POSIX regexp'ы, как те, что используются в egrep.

Единственное, что поначалу обескураживает - регулярные выражения нельзя заключать в кавычки. Ещё в первых версиях BASH 3.X можно было, а потом эту возможность убрали и теперь нужно пробелы экранировать, что конечно немного печально порой :)

DRVTiny ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.