(Отправленный, поскольку новый ответ, так как я не могу прокомментировать и редактирование, является слишком маленьким),
Можно закончить команду ""
препятствовать тому, чтобы пользователь выполнил команду с произвольными аргументами.
user ALL=(ALL:ALL) NOPASSWD: /path/to/your/script ""
Теперь sudo /path/to/your/script
работы, но sudo /path/to/your/script foo bar
сбои.
Можно достигнуть того, что Вы хотите с помощью маленького сценария Python (Вам будет нужен Python, установленный, а также lxml
инструментарий).
tagsort.py
:
#!/usr/bin/python
import sys
from lxml import etree
filename, tag = sys.argv[1:]
doc = etree.parse(filename, etree.XMLParser(remove_blank_text=True))
root = doc.getroot()
root[:] = sorted(root, key=lambda el: el.findtext(tag))
print etree.tostring(doc, pretty_print=True)
Этот сценарий сортирует элементы первого уровня под корнем XML-документа содержанием элемента второго уровня, отправляя результат в stdout. Это называют как это:
$ python tagsort.py filename tag
После того как у Вас есть это, можно использовать замену процесса для получения разности на основе ее вывода (я добавил один элемент и изменил другого в файлах в качестве примера для показа непустого результата):
$ diff <(python tagsort.py file1 Id) <(python tagsort.py file2 Id)
4a5
> <AddedTag>Something</AddedTag>
17c18
< <Role>X</Role>
---
> <Role>S</Role>
У меня была похожая проблема, и я в конце концов обнаружил: https://superuser.com/questions/79920/how-can-i-diff -two-xml-files
В этом посте предлагается выполнить каноническую сортировку xml, а затем выполнить сравнение. Следующее должно сработать для вас, если вы используете Linux, Mac или если у вас установлена ОС Windows, например cygwin:
$ xmllint --c14n File1.xml > 1.xml
$ xmllint --c14n File2.xml > 2.xml
$ diff 1.xml 2.xml
Это оболочка с тегами, но, честно говоря, я предпочитаю использовать язык сценариев с парсером. В данном случае perl
с XML :: Twig
.
Это выглядит примерно так:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
sub compare_by_identity {
my ( $first, $second ) = @_;
foreach my $identity ( $first->get_xpath('//Identity') ) {
my $id = $identity->first_child_text('Id');
print $id, "\n";
my $compare_to =
$second->get_xpath( "//Identity/Id[string()=\"$id\"]/..", 0 );
if ($compare_to) {
print "Matching element found for ID $id\n";
foreach my $element ( $identity->children ) {
my $tag = $element->tag;
my $text = $element->text;
if ( not $element->text eq $compare_to->first_child_text($tag) ) {
print "$id, $tag has value $text which doesn't match: ",
$compare_to->first_child_text($tag), "\n";
}
}
}
else {
print "No matching element for Id $id\n";
}
}
}
my $first_file = XML::Twig->new->parsefile('test1.xml');
my $second_file = XML::Twig->new->parsefile('test2.xml');
compare_by_identity( $first_file, $second_file );
compare_by_identity( $second_file, $first_file );
Я явно сравниваю один элемент Identity за раз и проверяю, все ли поля в одном существуют в другом с одинаковым значением.
И затем обратное, потому что второй файл может иметь дополнительные записи.