изменить строку и удалить тег, используя perl из xml-файла?

У меня есть xml-файл (client_23.xml) в котором мне нужно изменить одну строку и удалить из нее один цельный тэг, поэтому я придумал скрипт perl:

В моем XML-файле у меня есть блок вроде этого. В моем xml-файле будет только один экземпляр <hello>collect_model = 1</hello> :

 <world> <hello>collect_model = 1</hello> <hello>enable_data = 0</hello> <hello>session_ms = 2*60*1000</hello> <hello>max_collect = string_integer($extract("max_collect"))</hello> <hello>max_collect = parenting(max_collect, max_collect, 1.0e99)</hello> <hello>output('{')</hello> </world> 

Мне нужно изменить эту строку так: <hello>collect_model = 0</hello> поэтому после изменения весь мой блок должен выглядеть следующим образом:

 <world> <hello>collect_model = 0</hello> <hello>enable_data = 0</hello> <hello>session_ms = 2*60*1000</hello> <hello>max_collect = string_integer($extract("max_collect"))</hello> <hello>max_collect = parenting(max_collect, max_collect, 1.0e99)</hello> <hello>output('{')</hello> </world> 

Во-вторых, мне нужно удалить весь тег из одного и того же XML-файла:

 <derta-config> <data-users>2000</data-users> <test-users>2000</test-users> <attributes>hello world</attributes> <client-types>Client1</model-types> <target>price.world</target> </derta-config> 

Таким образом, у меня есть сценарий оболочки, в котором я использую perl, который пытается сделать выше двух вещей наряду с заменой некоторого содержимого в файле (что я делаю для какой-то другой цели), но часть, которую я добавил специально для выше двух, не работа и он начинает печатать кучу ошибок:

 perl -0pe "s#<eval>collect_model = 0</eval>#<eval>collect_model = 1</eval> s#<derta-config>.* </derta-config>##sm; s#<function>\s*<name>DUMMY_FUNCTION.+?</function>#$file#sm" client_"$client_id".xml > "$word"_new_file.xml 

Поэтому я думаю, что мы можем сделать это в сценарии оболочки вместо этого, имея в виду remvoe из этих двух вещей, используя сценарий оболочки, а затем вывод этого, мы можем перейти к моему скрипту perl, который работает на третьем шаге. Итак, мы можем передать вывод сценария оболочки, который удалит эти две вещи для меня ниже этого скрипта perl? Возможно ли это сделать?

 perl -0pe "s#<function>\s*<name>DUMMY_FUNCTION.+?</function>#$file#sm" client_"$client_id".xml > "$word"_dyn_model.xml 

Здесь $client_id равно 23 а $word abc .

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

2 Solutions collect form web for “изменить строку и удалить тег, используя perl из xml-файла?”

С этим в качестве образца входного файла:

 $ cat client_23.xml <world> <hello>collect_model = 1</hello> <hello>enable_data = 0</hello> <hello>session_ms = 2*60*1000</hello> <hello>max_collect = string_integer($extract("max_collect"))</hello> <hello>max_collect = parenting(max_collect, max_collect, 1.0e99)</hello> <hello>output('{')</hello> </world> <derta-config> <data-users>2000</data-users> <test-users>2000</test-users> <attributes>hello world</attributes> <client-types>Client1</model-types> <target>price.world</target> </derta-config> 

Мы можем сделать оба изменения, используя:

 $ sed 's|<hello>collect_model = 1</hello>|<hello>collect_model = 0</hello>|; \|<derta-config>|,\|</derta-config>|d' client_23.xml <world> <hello>collect_model = 0</hello> <hello>enable_data = 0</hello> <hello>session_ms = 2*60*1000</hello> <hello>max_collect = string_integer($extract("max_collect"))</hello> <hello>max_collect = parenting(max_collect, max_collect, 1.0e99)</hello> <hello>output('{')</hello> </world> 

Как это работает

У нас есть две команды sed. Первая – это замена, вторая – удаление:

  • s|<hello>collect_model = 1</hello>|<hello>collect_model = 0</hello>|

    Заменяющие команды имеют форму s|old|new| , Итак, здесь old – это оригинальный <hello>collect_model = 1</hello> а new – это замена <hello>collect_model = 0</hello> .

  • \|<derta-config>|,\|</derta-config>|d

    Это определяет диапазон строк. Стартовая строка содержит derta-config> а конечная строка содержит </derta-config> . Все строки в этом диапазоне удаляются командой d удаления.

Пожалуйста, не используйте регулярное выражение для синтаксического анализа XML. Это плохая идея. Основная причина, по которой это плохая идея, состоит в том, что в XML есть много разнообразия, и некоторые семантически идентичные XML могут иметь несколько существенно различное сопоставление шаблонов.

Рассмотрим строки, пробелы, унарные теги и т. Д.

 <element /> <element></element> 

Оба одинаковые – и тогда вы можете отступать, переводить строки, разделить теги и т. Д .:

 <element att1="fish" att2="carrot"> 

Также является действительным.

Поэтому я настоятельно рекомендую «использовать парсер». У Perl есть несколько вариантов – мне нравится XML::Twig :

 #!/usr/bin/env perl use strict; use warnings; use XML::Twig; my $twig = XML::Twig->new( 'pretty_print' => 'indented_a' )->parse( \*DATA ); foreach my $hello ( $twig->findnodes('//hello') ) { if ( $hello->trimmed_text =~ m/collect_model/ ) { $hello->set_text('collect_model = 0'); } } $_->delete for $twig->findnodes('//derta-config'); $twig->print; __DATA__ <root> <world> <hello>collect_model = 1</hello> <hello>enable_data = 0</hello> <hello>session_ms = 2*60*1000</hello> <hello>max_collect = string_integer($extract("max_collect"))</hello> <hello>max_collect = parenting(max_collect, max_collect, 1.0e99)</hello> <hello>output('{')</hello> </world> <derta-config> <data-users>2000</data-users> <test-users>2000</test-users> <attributes>hello world</attributes> <client-types>Client1</client-types> <target>price.world</target> </derta-config> </root> 

Потому что вам, похоже, нравится однострочное в perl:

 perl -MXML::Twig -0777 -e 'my $twig = XML::Twig->parse (<>); $_->set_text("collect_model = 0") for grep { $_->text =~ m/collect_model/ } $twig->findnodes("//hello"); $_->delete for $twig->findnodes("//derta-config"); $twig -> print;' 
  • Как сгенерировать HTML-отчет nmap с помощью python?
  • Как вставить переменные внутри строки, содержащей ""?
  • Измените текст в теге, но только тег содержится в определенном блоке XML
  • Как grep блок xml в XML-файле с использованием ключевого слова в ksh
  • извлекать блоки текста из xml-файла с условием
  • сравнить два файла XML
  • Удалить все узлы <FOLDER>! = Значение тега
  • Какой редактор можно использовать для выделения выделенных файлов проекта Mallard?
  • Как заменить «&» на «& amp;», за исключением того, что уже является частью XML-объекта?
  • Очистка объединенных файлов XML
  • Вставить строки после многострочного соответствия регулярному выражению
  • Linux и Unix - лучшая ОС в мире.