Использование XMLStarlet:
$ xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' -v 0220a file.xml
9999a
0220a
9999b
0220a
XPath //lcycl[@name="qc"]/prprvl
будет соответствовать узлу prprvl
, который является непосредственным дочерним узлом узла lcycl
, который имеет атрибут name
со значением qc
. Здесь xmlstarlet
изменит значение узла prprvl
на 0220a
независимо от того, каким было его начальное значение.
Если вы не хотите жестко кодировать значение 0220a
, а выбираете его из узла //lcycl[@name="tu"]/prprvl
, используйте
xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' \
-x '//lcycl[@name="tu"]/prprvl/text()' file.xml
Перенаправьте вывод в новый файл, а затем переименуйте новый файл в исходное имя.
Эквивалентная вещь в Perl,который возьмет file.xml
из текущего каталога:
#!/usr/bin/perl
use strict;
use warnings;
use XML::XPath;
use XML::XPath::XMLParser;
my $xp = XML::XPath->new( filename => 'file.xml' );
$xp->setNodeText( '//lcycl[@name="qc"]/prprvl', '0220a' );
my $nodeset = $xp->find('/');
foreach my $node ( $nodeset->get_nodelist() ) {
print XML::XPath::XMLParser::as_string($node);
}
Здесь, если вы хотите выбрать это значение из другого узла, используйте
$xp->setNodeText( '//lcycl[@name="qc"]/prprvl',
$xp->getNodeText('//lcycl[@name="tu"]/prprvl') );
вместо другой строки setNodeText()
.
Перенаправьте вывод в новый файл, а затем переименуйте новый файл в исходное имя.
Ошибка, которую вы получаете, связана с попыткой открыть файл с именем -
. GNU sed
будет рассматривать -
как стандартный входной поток, но другие sed
реализации (, например. BSDsed
)воспримет это как обычное имя файла.
В любом случае, вы не даете sed
никаких данных для работы. Это означает, что файл, на который вы перенаправляете, будет усечен и останется пустым.
Это было вызвано наличием всего 4096 обработчиков inotify. Я увеличил лимиты и проблема исчезла.
fs.file-max = 131070
fs.inotify.max_user_watches = 65536