Не используйте sed
с XML
. XML - это контекстная структура данных, а регулярное выражение просто не поддерживает этого. https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-conolated-tags
Используйте синтаксический анализатор. perl
имеет XML :: Twig
, который работает довольно хорошо:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
use XML::Twig;
my $xml_to_insert = XML::Twig -> parse ( '
Foo
Bar
') -> root -> copy;
my $xml = XML::Twig -> parse ( \*DATA );
$xml_to_insert -> paste ( 'first_child', $xml -> root );
$xml -> set_pretty_print ( 'indented_a');
$xml -> print;
__DATA__
Foo1
Bar1
Foo2
Bar2
Foo3
Bar3
Foo20432
Bar20432
Вывод:
Foo
Bar
Foo1
Bar1
Foo2
Bar2
Foo3
Bar3
Foo20432
Bar20432
Это длиннее и многословнее для иллюстрации - но, по сути, требует вашего фрагмента, и скопируйте его в вашу структуру. Красиво и просто.
XML :: Twig
также поддерживает "parsefile_inplace", который позволяет вам делать то же самое, что и sed -i
. Так что ваш пример будет выглядеть немного больше:
my $xml_to_insert = XML::Twig -> parsefile ( 'source.xml' ) -> root -> copy;
XML::Twig -> new ( pretty_print => 'indented_a',
twig_handlers => {
'foo:root' => sub {
$xml_to_insert -> paste ( 'first_child', $_ )
} }) -> parsefile_inplace ('sample.xml');
Или, если это выглядит слишком запутанным:
sub insert_source {
my ( $twig, $branch ) = @_;
my $xml_to_insert = XML::Twig -> parsefile ( 'source.xml' ) -> root -> copy;
$xml_to_insert -> paste ( 'first_child', $branch );
}
my $xml = XML::Twig -> new ( twig_handlers => { 'foo:root' => \&insert_source } );
$xml -> parsefile_inplace ( 'sample.xml');
To use it, insert it in a pipeline between two processes, with the appropriate options. Its standard input will be passed through to its standard output and progress will be shown on standard error.
Результат, который вы видите, получен из pv
. Индикатор выполнения находится на stderr, а содержимое, которое вы передали, — на stdout. Вы можете перенаправить вывод:
cmd | pv > /dev/null
и вы по-прежнему будете получать вывод индикатора выполнения.
Если команда создает свой собственный текст на stderr, вы можете перенаправить его явным образом в/dev/null
перед передачей вывода вpv
:
cmd 2>/dev/null | pv > /dev/null